Object obj = new Integer(2);
Byte b2 = (byte) obj; // at Runtime: ClassCastException "Integer cannot be cast to Byte"
我认为Integer(引用obj指向的)被解压缩为int,然后强制转换为byte,然后被压缩为byte并成功赋值。Eclipse编译器警告还说(稍微纠正一下):
那么为什么它不能将RHS中的这个字节分配到LHS中的字节引用中呢?
如果对象obj=新整数(2);
,则long b2=(long)obj;
工作,但long b2=7;
失败。字节b2=(byte)obj;
失败,但字节b2=7;
没问题!也许在这些相互的差异中有一些线索?
从经验上看,我会说,在解装箱后禁止对基元类型进行缩窄(即使使用显式强制转换)(而允许扩大)--这可以解释这种行为。
终于明白了:
如果变量的类型为:
并且常数表达式的值可以在类型Byte中表示。
并且常量表达式的值可以用Short类型表示。
Object o = new Integer(2);
Integer i2 = (Integer) o;
Integer i3 = (int) o;
Object obj = new Integer(2);
Byte b2 = (byte) obj;
装箱/取消装箱是静态地确定的,即在编译时。您已经强制转换为object
,因此编译器不知道obj
实际上是integer
类型。相反,它生成的字节码假定为byte
实例,以及一个显式检查(这是在运行时失败的检查):
ALOAD 1
CHECKCAST java/lang/Byte // Oh dear
INVOKEVIRTUAL java/lang/Byte.byteValue ()B // Unbox as a Byte
INVOKESTATIC java/lang/Byte.valueOf (B)Ljava/lang/Byte; // Box as a Byte
ASTORE 2
Integer obj = new Integer(2);
Byte b2 = (byte) obj;
第二行甚至不编译。(byte)obj
是一个强制转换上下文,有一系列规则定义这里允许的内容。1不允许先进行解装箱转换,然后进行缩小转换。
这些规则确实允许先进行解装箱转换,然后进行加宽转换,因此此代码编译并运行时不会出错:
Integer obj = new Integer(2);
Long b2 = (long) obj;
ALOAD 1
INVOKEVIRTUAL java/lang/Integer.intValue ()I // Unbox as an Integer
I2L // Convert to long
INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long; // Box as a Long
ASTORE 2
那么,您别无选择,只能执行相关的强制转换链:
Object obj = new Integer(2);
Byte b2 = (byte)(int)(Integer) obj;
为了完整起见,下面是相应的字节码:
ALOAD 1
CHECKCAST java/lang/Integer // This is now ok
INVOKEVIRTUAL java/lang/Integer.intValue ()I // Unbox as an Integer
I2B // Convert to byte
INVOKESTATIC java/lang/Byte.valueOf (B)Ljava/lang/Byte; // Box as a Byte
ASTORE 2
1。注意,由于=
,这里还有一个赋值上下文,它有自己的一组规则。除其他外,不能执行长b2=7;
,因为没有任何东西允许加宽转换后进行装箱转换。
描述 (Description) java.lang.reflect.Field.setByte(Object obj, byte value)方法将字段的值设置为指定对象上的字节。 声明 (Declaration) 以下是java.lang.reflect.Field.setBoolean(Object obj, byte value)方法的声明。 public void setByte(Obj
本文向大家介绍请编写一个对象obj满足 obj=='a' && obj=='b' && obj=='c'相关面试题,主要包含被问及请编写一个对象obj满足 obj=='a' && obj=='b' && obj=='c'时的应答技巧和注意事项,需要的朋友参考一下
描述 (Description) java.lang.reflect.Field.getByte(Object obj)方法获取静态或实例字节字段的值。 声明 (Declaration) 以下是java.lang.reflect.Field.getByte(Object obj)方法的声明。 public byte getByte(Object obj) throws IllegalArgu
问题内容: 我的老板说我应该使用,因为它比更好,但是他不记得为什么这样做。有什么理由要使用吗? 我以某种方式感觉到…相反! 在Google上进行搜索后,我发现的唯一结果是: 在C语言中,它可以防止您意外地在条件结构中键入(obj = null)。 问题答案: 您不能通过输入来意外分配给它。但是,这是C时代的回忆,在Java中是不可能的,因为表达式返回赋值的右侧。由于不是,编译器会抱怨。 我会尽力向
问题内容: 我试图了解何时以及如何在Python中正确使用super()(2.7.x或3.x) 在翻译告诉我怎么称呼它: 我了解在Python3.x中现在可以在类定义中使用super(),但是我不明白为什么不可能。或在类定义中。 我知道一定有原因,但是我找不到。对我来说,这些行等于或,并且行得通吗? 我认为即使在Python 3.x中,键入也是一个不错的快捷方式。 问题答案: 仅在Python 2
对于那些不知道_. allKeys(obj)做什么的人,这里有一个片段 因此,它返回传递给它的对象的属性/方法名称数组。 这应该给我: 属性名称:firstname 值名称:John ------ 属性名称:lastname 值名称:Adams ------ 相反,它给了我: 属性名称:firstname 值名称:un定义 ------ 属性名称:lastname 值名称:un定义 ------