Какая-либо причина предпочесть getClass () по instanceof при генерации .equals ()?

используйте getApplicationContext() вместо this в обоих действиях как:

. В активности A SharedPreferences следующим образом:

 private void SavePreferences(String key, String value){
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, value);
        editor.commit();
        Intent sd=new Intent(this,Secongtess.class);
        startActivity(sd);
       }

и в действии B получают значение as :

 private void LoadPreferences(){   
       SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
     String  data = sharedPreferences.getString("name", "08:00") ;
     Toast.makeText(this,data, Toast.LENGTH_LONG).show();
   }

, поскольку, поскольку doc говорит:

getDefaultSharedPreferences (контекст контекста) :

Получает экземпляр SharedPreferences который указывает на файл по умолчанию, который используется средой предпочтений в данном контексте.

blockquote>

167
задан Kip 27 February 2009 в 20:14
поделиться

9 ответов

Если Вы будете использовать instanceof, делая Ваш equals, то реализация final сохранит контракт симметрии метода: x.equals(y) == y.equals(x). Если final кажется строгим, тщательно исследуйте свое понятие объектной эквивалентности, чтобы удостовериться, что Ваши переопределяющие реализации полностью поддерживают контракт, установленный Object класс.

96
ответ дан erickson 4 November 2019 в 16:40
поделиться

Josh Bloch польза Ваш подход:

причина, что я одобряю эти instanceof подход, состоит в том, что, когда Вы используете эти getClass подход, у Вас есть ограничение, которое объекты только равны другим объектам того же класса, того же типа выполнения. Если Вы расширите класс и добавите несколько безвредных методов к нему, то проверьте, чтобы видеть, равен ли некоторый объект подкласса объекту суперкласса, даже если объекты равны по всем важным аспектам, то Вы получите удивительный ответ, что они не равны. На самом деле это нарушает строгую интерпретацию принцип замены Лисков и может привести к очень удивительному поведению. В Java это особенно важно, потому что большинство наборов (HashTable, и т.д.) на основе, равняется методу. Если Вы поместите члена суперкласса в хэш-таблице как ключ и затем посмотрите он использование экземпляра подкласса, то Вы не найдете его, потому что они не равны.

Видят также это, ТАК ответьте .

Эффективная глава 3 Java также касается этого.

172
ответ дан Community 4 November 2019 в 16:40
поделиться

Angelika Langers Секреты равняются , входит в это с долгим и детальным обсуждением для нескольких общих и известных примеров, включая Josh Bloch и Barbara Liskov, обнаруживая несколько проблем в большинстве из них. Она также входит instanceof по сравнению с getClass. Некоторая кавычка от него

Заключения

разделявший четыре произвольно выбранных примера реализаций равняются (), что мы завершаем?

, В первую очередь: существует два существенно различных способа выполнить проверку для соответствия типа в реализации, равняется (). Класс может позволить смешанное сравнение типов супер - и разделить объекты на подклассы посредством оператора instanceof, или класс может рассматривать объекты другого типа как неравные посредством getClass () тест. Примеры выше проиллюстрированного приятно, что реализации равняются () использующий getClass () обычно более устойчивы, чем те реализации с помощью instanceof.

тест instanceof корректен только для заключительных классов или если, по крайней мере, метод равняется (), является окончательным в суперклассе. Последний по существу подразумевает, что никакой подкласс не должен расширять состояние суперкласса, но может только добавить функциональность или поля, которые не важны для состояния и поведения объекта, таковы как переходные или статические поля.

Реализации с помощью getClass () тест, с другой стороны, всегда соответствуют равнянию () контракт; они корректны и устойчивы. Они, однако, семантически очень отличаются от реализаций, которые используют тест instanceof. Реализации с помощью getClass () не позволяют сравнение под - с суперобъектами класса, даже когда подкласс не добавляет полей и даже не хотел бы переопределять, равняется (). Такое "тривиальное" расширение класса, например, было бы добавлением метода печати отладки в подклассе, определенном для точно этой "тривиальной" цели. Если бы суперкласс запрещает смешанное сравнение типов через getClass () проверка, то тривиальное расширение не было бы сопоставимо со своим суперклассом. Является ли это проблемой, полностью зависит от семантики класса и цели расширения.

64
ответ дан Johannes Schaub - litb 4 November 2019 в 16:40
поделиться

Это - что-то вроде религиозных дебатов. Оба подхода имеют свои проблемы.

  • Использование instanceof и Вы никогда не можете добавлять значительных участников к подклассам.
  • Использование getClass и Вы нарушаете принцип замены Лисков.

Bloch имеет другой соответствующий совет в Эффективный Java Второй Выпуск :

  • Объект 17: Дизайн и документ для наследования или запрещают его
26
ответ дан user11153 4 November 2019 в 16:40
поделиться

Если Вы хотите удостовериться только, что класс будет соответствовать тогда использованию getClass() ==. Если Вы хотите соответствовать подклассам тогда instanceof, необходим.

кроме того, instanceof не будет соответствовать против пустого указателя, но безопасен выдержать сравнение с пустым указателем. Таким образом, Вы не должны аннулировать, проверяют его.

if ( ! (obj instanceof MyClass) ) { return false; }
5
ответ дан Clint 4 November 2019 в 16:40
поделиться

Оба метода имеют свои проблемы.

, Если подкласс изменяет идентификационные данные, то необходимо сравнить их фактические классы. Иначе Вы нарушаете симметричное свойство. Например, различные типы Person с нельзя считать эквивалентной, даже если у них есть то же имя.

Однако некоторые подклассы не изменяют идентификационные данные, и они должны использовать instanceof. Например, если у нас есть набор неизменных Shape, объекты, затем Rectangle с длиной и шириной 1 должны быть равны единице Square.

На практике, я думаю, что бывший случай, более вероятно, будет верен. Обычно, разделение на подклассы является фундаментальной частью Ваших идентификационных данных, и бывший похожий точно на Вашего родителя кроме Вас может сделать того, которому мало вещи не заставляет Вас равняться.

2
ответ дан James 4 November 2019 в 16:40
поделиться

instanceof работает на экземпляры того же класса или свои подклассы

, можно использовать его, чтобы протестировать, если объект является экземпляром класса, экземпляром подкласса или экземпляром класса, который реализует конкретный интерфейс.

ArryaList и RoleList оба Список instanceof

, В то время как

getClass () == o.getClass () будет верен, только если оба объекта (это и o) принадлежат точно тому же классу.

Так в зависимости от того, что необходимо сравнить, Вы могли использовать один или другой.

, Если Ваша логика: "Каждый возражает, равняется другому, только если они - оба тот же класс", необходимо пойти для "равняния", которое я думаю, большинство случаев.

3
ответ дан OscarRyz 4 November 2019 в 16:40
поделиться

Это зависит, если Вы рассматриваете, ли подкласс данного класса, равняется его родителю.

class LastName
{
(...)
}


class FamilyName
extends LastName
{
(..)
}

здесь я использовал бы 'instanceof', потому что я хочу, чтобы LastName сравнился с FamilyName

class Organism
{
}

class Gorilla extends Organism
{
}

здесь, я использовал бы 'getClass', потому что класс уже говорит, что эти два экземпляра не эквивалентны.

5
ответ дан Pierre 4 November 2019 в 16:40
поделиться

Причина использовать getClass состоит в том, чтобы гарантировать симметричное свойство эти equals контракт. От JavaDocs equal:

Это симметрично: поскольку любая ненулевая ссылка оценивает X и Y, x.equals (y) должен возвратить true, если и только если y.equals (x) возвращает true.

При помощи instanceof, возможно не быть симметричным. Рассмотрите пример: Собака расширяет Животное. Животное equals делает instanceof проверка Животного. Собака equals делает instanceof проверка Собаки. Дайте Животное и Собака d (с другими полями то же):

a.equals(d) --> true
d.equals(a) --> false

Это нарушает симметричное свойство.

Для строгого следования контракту equal симметрия должна быть обеспечена, и таким образом класс должен быть тем же.

56
ответ дан Steve Kuo 4 November 2019 в 16:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: