如何将字符串转换为整数?
How can a string be casted to an Integer?
LinkedList<Integer> adjMatrix[] = new LinkedList[10];
Object[] temp = (Object[]) adjMatrix;
LinkedList<String> string = new LinkedList<String>();
string.add("abc");
temp[3] = string;
System.out.println(adjMatrix[3].get(0));
//prints abc
//====================================================
LinkedList<String>[] stringList = new LinkedList[10];
Object[] oa = (Object[]) stringList;
LinkedList<Integer> listInt = new LinkedList<Integer>();
listInt.add(new Integer(3));
oa[1] = listInt;
System.out.println(stringList[1].get(0));
// gives ClassCastException java.lang.Integer cannot be cast to java.lang.String
我对第一种情况到底发生了什么感到困惑,一个整数接受了一个字符串值,但在第二种情况中并没有发生。有什么想法吗?
第一个例子创建了一个损坏的数组。这就是您在尝试使用泛型数组时收到警告的原因,因为 JVM 无法强制执行类型安全。
记住,由于类型擦除,LinkedList<Integer> adjMatrix[]
在运行时实际上是一个LinkedList adjMatrix[]
,即它可以存储所有对象类型。
在第一种情况下,您只是在打印 adjMatrix[3].get(0)
。编译器认为这个表达式是一个整数。但实际类型并不重要:生成的 byte-code 是
37: invokevirtual #8 // Method java/util/LinkedList.get:(I)Ljava/lang/Object;
40: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
所以它只是将它从列表中获得的对象传递给 PrintStream.println(Object)
,然后它会对该对象调用 String.value()
。编译器从不向 byte-code 添加强制转换,因为没有必要。
在第二种情况下,您打印 stringList[1].get(0)+""
,编译器认为它是字符串与空字符串的串联。所以生成的byte-code是
101: invokevirtual #8 // Method java/util/LinkedList.get:(I)Ljava/lang/Object;
104: checkcast #14 // class java/lang/String
107: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
110: ldc #16 // String
112: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
115: invokevirtual #17 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
118: invokevirtual #18 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
如你所见,这里有一个checkcast指令,因为字节码需要调用StringBuilder.append(String)
,因此需要将表达式强制转换为String。因为它实际上是一个整数,所以它抛出一个 ClassCastException。
LinkedList<Integer> adjMatrix[] = new LinkedList[10];
Object[] temp = (Object[]) adjMatrix;
LinkedList<String> string = new LinkedList<String>();
string.add("abc");
temp[3] = string;
System.out.println(adjMatrix[3].get(0));
//prints abc
//====================================================
LinkedList<String>[] stringList = new LinkedList[10];
Object[] oa = (Object[]) stringList;
LinkedList<Integer> listInt = new LinkedList<Integer>();
listInt.add(new Integer(3));
oa[1] = listInt;
System.out.println(stringList[1].get(0));
// gives ClassCastException java.lang.Integer cannot be cast to java.lang.String
我对第一种情况到底发生了什么感到困惑,一个整数接受了一个字符串值,但在第二种情况中并没有发生。有什么想法吗?
第一个例子创建了一个损坏的数组。这就是您在尝试使用泛型数组时收到警告的原因,因为 JVM 无法强制执行类型安全。
记住,由于类型擦除,LinkedList<Integer> adjMatrix[]
在运行时实际上是一个LinkedList adjMatrix[]
,即它可以存储所有对象类型。
在第一种情况下,您只是在打印 adjMatrix[3].get(0)
。编译器认为这个表达式是一个整数。但实际类型并不重要:生成的 byte-code 是
37: invokevirtual #8 // Method java/util/LinkedList.get:(I)Ljava/lang/Object;
40: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
所以它只是将它从列表中获得的对象传递给 PrintStream.println(Object)
,然后它会对该对象调用 String.value()
。编译器从不向 byte-code 添加强制转换,因为没有必要。
在第二种情况下,您打印 stringList[1].get(0)+""
,编译器认为它是字符串与空字符串的串联。所以生成的byte-code是
101: invokevirtual #8 // Method java/util/LinkedList.get:(I)Ljava/lang/Object;
104: checkcast #14 // class java/lang/String
107: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
110: ldc #16 // String
112: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
115: invokevirtual #17 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
118: invokevirtual #18 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
如你所见,这里有一个checkcast指令,因为字节码需要调用StringBuilder.append(String)
,因此需要将表达式强制转换为String。因为它实际上是一个整数,所以它抛出一个 ClassCastException。