public class MyJava { public final int bx = 20;//这里声明的是int类型
public static void main(String[] args) { MyJava obj = new MyJava(); obj.make(); byte b = obj.bx; // 编译失败,需要强制转换为byte:byte b = (byte)obj.bx; }
public void make() { byte b = bx; // 编译成功 } }
发现bx在-128~127之间的时候,make()编译能通过 其他数值都会报损失精度 猜测原因 在类中,因为 public final int bx = 20; 是一个常量,编译期就已经确定他的值了 所以当bx的范围在byte范围中时,make()就不会报错 而byte b = obj.bx;在类的外部,编译器,不知道obj.bx是什么,所以直接报错了
也不对啊,那我如果将make()方法中的“byte b = bx;”改成“byte b = this.bx;”,就也报错了
呃,好诡异的行为. 难道说前面带xxx.bx这样引用出来的就要报错...
his.bx跟obj.bx是一个性质的吧,所以报错啊。而byte b = bx;已经直接知道了bx的类型..
大哥,你两个星怎么来的啊? public static final int bx = 20;
“this.bx跟obj.bx是一个性质的吧,所以报错啊。而byte b = bx;已经直接知道了bx的类型..”这句话怎么说 this和obj引用是一个性质?
final int是编译期常量, 具有不变性。 obj.make(); byte b = obj.bx; // 编译失败 你make()赋一次值,下面一句又赋一次值, 你那相当于重复赋值,当然报错。
-128~127,make()能编译过,应该是跟Integer里面存有一个[-128]到[127]的静态cache数组有关,至于为什么,偶也没想通 Integer在自动装箱(非new)时,数值在-128~127之间,会直接去cache里的,所以同一数值的对象其实是一个对象,只有范围在这个之外才会new Integer public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i); } private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; // high value may be configured by property int h = 127; if (integerCacheHighPropValue != null) { // Use Long.decode here to avoid invoking methods that // require Integer's autoboxing cache to be initialized int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} }
public final int bx = 20;//这里声明的是int类型
public static void main(String[] args) {
MyJava obj = new MyJava();
obj.make();
byte b = obj.bx; // 编译失败,需要强制转换为byte:byte b = (byte)obj.bx;
}
public void make() {
byte b = bx; // 编译成功
}
}
其他数值都会报损失精度
猜测原因
在类中,因为 public final int bx = 20; 是一个常量,编译期就已经确定他的值了
所以当bx的范围在byte范围中时,make()就不会报错
而byte b = obj.bx;在类的外部,编译器,不知道obj.bx是什么,所以直接报错了
也不对啊,那我如果将make()方法中的“byte b = bx;”改成“byte b = this.bx;”,就也报错了
难道说前面带xxx.bx这样引用出来的就要报错...
his.bx跟obj.bx是一个性质的吧,所以报错啊。而byte b = bx;已经直接知道了bx的类型..
大哥,你两个星怎么来的啊?
public static final int bx = 20;
obj.make();
byte b = obj.bx; // 编译失败
你make()赋一次值,下面一句又赋一次值,
你那相当于重复赋值,当然报错。
Integer在自动装箱(非new)时,数值在-128~127之间,会直接去cache里的,所以同一数值的对象其实是一个对象,只有范围在这个之外才会new Integer public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
} private static class IntegerCache {
static final int high;
static final Integer cache[]; static {
final int low = -128; // high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
} private IntegerCache() {}
}