Perché non è possibile eseguire il cast di Integer su String in java?


95

Ho trovato qualche strana eccezione:

java.lang.ClassCastException: java.lang.Integer 
 cannot be cast to java.lang.String

Come può essere possibile? Ogni oggetto può essere lanciato su String, non è vero?

Il codice è:

String myString = (String) myIntegerObject;

Grazie.


11
"Ogni oggetto può essere lanciato su String" - Questo è sbagliato. Piuttosto, ogni oggetto ha un toString()metodo che lo convertirà in una stringa. Come sottolineano diverse risposte, questo è ciò che dovresti usare. (Per alcuni oggetti, toString()non restituisce una stringa molto utile , ma Integerprobabilmente fa esattamente quello che vuoi.)
Ted Hopp

2
""+myIntegerObjectfunziona anche :)
Salman von Abbas

1
Nel mio caso, questo errore è stato segnalato per colpa ... stavo usando Integer.toString(IntegerObject)e mi ha dato questo errore, ma è soddisfatto di IntegerObject.toString()... E sì, questo è davvero un numero intero, e ho davvero ricevuto questo errore ...
Andrew

Gratta quello, String.valueOf()funziona davvero solo ...
Andrew

Risposte:


155

Perché questo non è possibile:

Perché String e Integer non si trovano nella stessa gerarchia di oggetti.

      Object
     /      \
    /        \
String     Integer

Il casting che stai provando, funziona solo se sono nella stessa gerarchia, ad es

      Object
     /
    /
   A
  /
 /
B

In questo caso, (A) objBo (Object) objBo (Object) objAfunzionerà.

Quindi, come altri hanno già detto, per convertire un intero in una stringa usa:

String.valueOf(integer), o Integer.toString(integer)per primitivo,

o

Integer.toString() per l'oggetto.


Che dire di (A) objA, (B) objB e (B) objA?
su-ex

@ su-ex (B) objAnon funzionerà. (A) objAe (B) objBfunzionerà.
Bhushan

Spiacenti, hai ragione, questo dà un'eccezione ClassCastException. Gli altri due sono abbastanza inutili ma funzioneranno ovviamente.
su-ex

45

No, Integere Stringsono tipi diversi. Per convertire un intero in una stringa usa:, String.valueOf(integer)o Integer.toString(integer)per primitivo, o Integer.toString()per l'oggetto.


1
@ Ted Hopp - quale? Se è un primitivo usa i primi due, se è l'oggetto Integer usa il terzo.
Petar Minchev

Ops. Non ho visto l'ultima frase della tua risposta. Sto cancellando il mio commento e voto questa risposta.
Ted Hopp

1
Problema simile (ma non duplicato): non è possibile eseguire il cast di un "int" su una stringa perché un "int" non è un oggetto, tanto meno nella gerarchia della stringa.
Kelly S. French,

20

Per i inttipi utilizzare:

int myInteger = 1;
String myString = Integer.toString(myInteger);

Per i Integertipi utilizzare:

Integer myIntegerObject = new Integer(1);
String myString = myIntegerObject.toString();

Questo forza un'operazione di unboxing non necessaria.
Ted Hopp

@Ted Hopp vedi le mie modifiche per chiarire quando utilizzare ogni tipo di toString()metodo
DRiFTy

Penso che l'ultima riga dovrebbe essereString myString = myIntegerObject.toString();
Ted Hopp

6

No. Ogni oggetto può essere lanciato a un java.lang.Object, non a String. Se vuoi una rappresentazione di stringa di qualsiasi oggetto, devi invocare il toString()metodo; non è la stessa cosa che lanciare l'oggetto su una stringa.


5

Gli oggetti possono essere convertiti in una stringa utilizzando il toString()metodo:

String myString = myIntegerObject.toString();

Non esiste una regola del genere sul casting . Affinché il casting funzioni, l'oggetto deve essere effettivamente del tipo a cui stai eseguendo il casting.


5

Non puoi trasmettere esplicitamente nulla a un file Stringche non sia a String. Dovresti usare uno:

"" + myInt;

o:

Integer.toString(myInt);

o:

String.valueOf(myInt);

Preferisco la seconda forma, ma credo sia una scelta personale.

Modifica OK, ecco perché preferisco la seconda forma. La prima forma, una volta compilata, potrebbe istanziare a StringBuffer(in Java 1.4) o a StringBuilderin 1.5; un'altra cosa da raccogliere nella spazzatura. Il compilatore non lo ottimizza per quanto ne so. La seconda forma ha anche un analogo, Integer.toString(myInt, radix)che ti permette di specificare se vuoi esadecimale, ottale, ecc. Se vuoi essere coerente nel tuo codice (puramente esteticamente, immagino) la seconda forma può essere usata in più posti.

Modifica 2 Ho pensato che volessi dire che il tuo numero intero fosse un inte non un Integer. Se è già un Integer, usalo toString()e fallo.


OP sta iniziando con un oggetto Integer. È molto più efficiente da fare myIntegerObject.toString().
Ted Hopp

4

Dovresti chiamare myIntegerObject.toString () se vuoi la rappresentazione di stringa.


2

Il casting è diverso dalla conversione in Java, per usare una terminologia informale.

Eseguire il cast di un oggetto significa che l'oggetto è già ciò a cui lo stai trasmettendo e lo stai solo dicendo al compilatore. Ad esempio, se ho un Fooriferimento che so essere FooSubclassun'istanza, allora (FooSubclass)Foodice al compilatore, "non modificare l'istanza, sappi solo che in realtà è un file FooSubclass.

D'altra parte, an nonInteger è a , sebbene (come fai notare) ci siano metodi per ottenere a che rappresenta un . Dal momento che nessun alcuna istanza di può mai essere una , non puoi lanciare a .StringStringIntegerIntegerStringIntegerString


1

Nel tuo caso non è necessario il casting, devi chiamare toString ().

Integer i = 33;
String s = i.toString();
//or
s = String.valueOf(i);
//or
s = "" + i;

Casting. Come funziona?

Dato:

class A {}
class B extends A {}

(A)
  |
(B)

B b = new B(); //no cast
A a = b;  //upcast with no explicit cast
a = (A)b; //upcast with an explicit cast
b = (B)a; //downcast

A e B nello stesso albero ereditario e possiamo questo:

a = new A();
b = (B)a;  // again downcast. Compiles but fails later, at runtime: java.lang.ClassCastException

Il compilatore deve consentire cose che potrebbero funzionare in fase di esecuzione. Tuttavia, se il compilatore sa al 100% che il cast non potrebbe funzionare, la compilazione fallirà.
Dato:

class A {}
class B1 extends A {}
class B2 extends A {}

        (A)
      / \
(B1) (B2)

B1 b1 = new B1();
B2 b2 = (B2)b1; // B1 can't ever be a B2

Errore: tipi invertibili B1 e B2. Il compilatore sa al 100% che il cast non potrebbe funzionare. Ma puoi imbrogliare il compilatore:

B2 b2 = (B2)(A)b1;

ma comunque in fase di esecuzione:

Eccezione nel thread "main" java.lang.ClassCastException: impossibile eseguire il cast di B1 su B2

nel tuo caso:

          (Oggetto)
            / \
(Intero) (Stringa)

Integer i = 33;
//String s = (String)i; - compiler error
String s = (String)(Object)i;

in fase di esecuzione: eccezione nel thread "main" java.lang.ClassCastException: java.lang.Integer non può essere cast su java.lang.String


0

Usa String.valueOf (intero) .

Restituisce una rappresentazione di stringa di numero intero.


Come dice Petar sopra, dovrebbe essereString.valueOf(integer)
Urs Reupke

@ UrsReupke: grazie, in realtà quando stavo cercando di aggiungere il collegamento l'ho riscritto in modo sbagliato.
RanRag

0

Usa .toString invece come di seguito:

String myString = myIntegerObject.toString();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.