2015-04-23 9 views
5

Perché ...controllo uguaglianza oggetto di riferimento utilizzando == (in Java)

String a = new String("a"); 
    StringBuilder b = new StringBuilder("a"); 
    System.out.println(a==b); 

... provocare un errore tipi incompatibili durante la compilazione, dato che ...

String a = new String("b"); 
    Object b = new StringBuilder("b"); 
    System.out.println(a==b); 

. .. non?

Perché è possibile confrontare i riferimenti oggetto di una stringa e un oggetto ma non un oggetto StringBuilder e una stringa? Non sono tutti solo indirizzi alle posizioni di memoria?

Grazie

+3

La stringa è 'Object' non' StringBuilder'. – Masudul

+0

Sarebbe mai possibile che i riferimenti 'String' e' StringBuilder' abbiano la stessa istanza? Se no allora qual è il punto del test 'a == b'? Ora sarebbe possibile che i riferimenti 'Object' e' StringBuilder' conservino le stesse istanze? – Pshemo

risposta

4

di tronchi con il linguaggio Java Specification (15.21.3):

Si tratta di un errore di compilazione se è impossibile convertire il tipo di entrambi gli operandi al tipo dell'altro mediante una conversione di fusione (§5.5). I valori di runtime dei due operandi sarebbero necessariamente non uguali (ignorando il caso in cui entrambi i valori sono nulli).

Il che significa, per "confrontare" due tipi di riferimento, uno deve essere in grado di essere trasmesso all'altro. La stringa "è" un oggetto, ma non vi è alcun "cast" tra String e StringBuilder.

+0

Mi riferirò alle specifiche prima in futuro. Grazie – Kayl669

3

Il compilatore tenta di aiutarti.

Quando il == non può mai essere vero a causa di tipi in conflitto, si presuppone che si sia commesso un errore e si rifiuta di compilare il codice.

Accade anche con instanceof e anche con i cast.

String a = null; 
if (a instanceof StringBuilder){} // compile-error 
StringBuilder b = (StringBuilder) a; // compile-error 
2

String estende il tipo Object, come qualsiasi altra classe, ma non eredita StringBuilder. Quindi nel tuo confronto String torna a Object e loro hanno un tipo in comune.

1

Poiché sia ​​Stringhe che StringBuilder sono figli della classe Object. Tuttavia, non sono della stessa classe, quindi non possono essere confrontati utilizzando ==. Dovresti chiamare il metodo toString su StringBuilder.

0

Nel secondo esempio String è anche un oggetto poiché tutte le classi sottoclasse Object e si può controllare se sono ==.

Nel primo esempio si confronta String in StringBuilder che sono classi diverse e nessuna delle due è sottoclasse dell'altra, pertanto l'operatore non riesce.

3

Perché, String è un Object ma String non è StringBuilder. È possibile confrontare il riferimento utilizzando == sullo stesso tipo e supertipo. Guardate seguente esempio

class A{ 

} 
class B extends A{ 

} 

class C{ 

} 

Ora,

A a =new A(); 
    A b =new B(); // or B b =new B(); 
    C c= new C(); 

    System.out.println(a==b); // It is ok 
    System.out.println(a==c); // It will generate compile time error 
+0

o B b = nuovo B(); come il richiedente ha appena dimostrato che questo commento non è corretto –

0

Poiché è necessario confrontare i tipi compatibili, poiché il confronto di tipi incompatibili per l'uguaglianza sarà sempre false.

String è compatibile con Object, quindi confrontando i riferimenti con quei tipi non è un errore di compilazione. StringBuilder è compatibile con Object, quindi è possibile assegnare un StringBuilder a una variabile di tipo Object. Ma String e StringBuilder non sono compatibili con a vicenda. Pertanto, se si dispone di un riferimento String e di un riferimento Object, è possibile confrontarli senza un errore in fase di compilazione. Ma se si dispone di un riferimento String e di un riferimento StringBuilder, non è possibile   — il compilatore sa che il confronto non sarà mai true.

Nota come si tratta del tipo di riferimenti (le variabili), non del tipo di oggetti ad essi assegnati. Ecco perché è possibile impostare il secondo scenario e farlo compilare, anche se non può mai avere un risultato reale.

Problemi correlati