2015-02-23 3 views
2
public class Main { 
    static class A {}; 

    static class B {}; 

    public static void main(String[] args) { 
     Class<?> r1 = new A().getClass(); 
     Class<?> r2 = new B().getClass(); 

     boolean a = (r1 == r2); //it is ok 
     boolean b = (new A().getClass() == new B().getClass()); //compilation error 
    } 
} 

r1 является ссылкой на тип Class<A> и r2 является ссылкой на тип Class<B>. Я думаю, это неправильно сравнивать. Но компилятор не создает ошибку в строке «boolean a = (r1 == r2);« Почему? Как это работает с точки зрения безопасности типа дженериков?сравнения ссылок на общие классы

Например, вы не можете сравнить «boolean c = (new ArrayList<String>() == new ArrayList<Integer>());», компилятор говорит «несравненные типы».

+0

Если вы хотите проверить класс объекта, используйте 'instanceof'. – m0skit0

+1

Вы имели в виду '.getClass()' в сравнении последнего абзаца? – arootbeer

+0

Но вы не можете сравнивать их таким образом, что OP намеревается –

ответ

4

r1 и r2 может содержать ссылку любого Class, например, и, следовательно, они могут содержать ссылку на тот же Class. Поэтому компилятор позволяет это сравнение.

Когда вы сравниваете связанные экземпляры класса в - new A().getClass() == new B().getClass() - компилятор знает, что они не одного типа и, следовательно, не позволяют этого.

+0

Спасибо! Можете ли вы дать ссылку на стандарт java или, возможно, еще один ресурс, чтобы глубже ознакомиться с шаблонами подстановочных и сопоставленных подстановочных знаков? –

1

Первое - вы не можете сравнивать классы, используя только ссылки. Если вы хотите, чтобы классы были одного типа, вам нужно использовать оператор instanceof в java.

1

В первом случае вы сравниваете ссылку на класс со ссылкой на другой класс.

Во втором случае вы сравниваете ссылку на объект типа A со ссылкой на объект типа B, который недопустим.

От The Java Language Specification:

Это ошибка времени компиляции, если это невозможно преобразовать тип либо операнд к типу другого путем преобразования литья (§5.5). Значения времени выполнения двух операндов обязательно равны .

В первом случае класс бросает в ролях, но во втором случае, ни Б бросает к А, ни бросает в B.

0

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

public class Main { 
    static class A {}; 

    static class B {}; 

    public static void main(String[] args) {  
     A objA = new A(); 
     B objB = new B(); 

     if (objA instanceof A) { 
      System.out.println("objA is an instance of A); 
     } 
     if (objB instanceof B) { 
      System.out.println("objB is an instance of B); 
     } 
    } 
} 

Это, как вы проверяете классы определенного типа с помощью оператора InstanceOf в Java.

Смежные вопросы