这个常量是什么情况?

chenchengamao 2011-09-09 04:22:23

public class MyJava {
public final int bx = 20;

public static void main(String[] args) {
MyJava obj = new MyJava();
obj.make();
byte b = obj.bx; // 编译失败
}

public void make() {
byte b = bx; // 编译成功
}
}
...全文
280 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
猫蹄 2011-09-15
  • 打赏
  • 举报
回复
-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() {}
}



[Quote=引用 7 楼 skyparty 的回复:]
发现bx在-128~127之间的时候,make()编译能通过
其他数值都会报损失精度
猜测原因
在类中,因为 public final int bx = 20; 是一个常量,编译期就已经确定他的值了
所以当bx的范围在byte范围中时,make()就不会报错
而byte b = obj.bx;在类的外部,编译器,不知道obj.bx是什么,所以直接报错了
[/Quote]
chenchengamao 2011-09-14
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 iambic 的回复:]

编译器不够聪明而已吧。深入讨论意义也不大。
[/Quote]

有可能。。。
chenchengamao 2011-09-11
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 ydj552110737 的回复:]

第一行出错是因为加上obj编译器认为那是个对象的属性所以会出错,而下面的直接调用相当于直接调用的常量(bx定义成final就是个常量)也就是20, 20在byte的范围内所以编译不会出错。这是我跟同学老师们讨论出的结果 希望对楼主有帮助
[/Quote]


哇,都叫上同学和老师的,感激不尽啊。。。。哈哈
ydj552110737 2011-09-11
  • 打赏
  • 举报
回复
第一行出错是因为加上obj编译器认为那是个对象的属性所以会出错,而下面的直接调用相当于直接调用的常量(bx定义成final就是个常量)也就是20, 20在byte的范围内所以编译不会出错。这是我跟同学老师们讨论出的结果 希望对楼主有帮助
阳明 to life 2011-09-11
  • 打赏
  • 举报
回复
没头绪 留名学习
li5610 2011-09-11
  • 打赏
  • 举报
回复
用(byte b = obj.bx;)对象调用的是引用类型,(byte b=bx;)是值类型
  • 打赏
  • 举报
回复
final int是编译期常量, 具有不变性。
obj.make();
byte b = obj.bx; // 编译失败
你make()赋一次值,下面一句又赋一次值,
你那相当于重复赋值,当然报错。
iambic 2011-09-11
  • 打赏
  • 举报
回复
编译器不够聪明而已吧。深入讨论意义也不大。
ccamao 2011-09-10
  • 打赏
  • 举报
回复
这个问题确实很奇怪
chenchengamao 2011-09-09
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 fainfy 的回复:]

引用楼主 chenchengamao 的回复:
Java code

public class MyJava {
public final int bx = 20;

public static void main(String[] args) {
MyJava obj = new MyJava();
obj.make();
byte b = obj.bx; ……
……
[/Quote]


你改完后正确了吗?你两个星怎么来的啊?
chenchengamao 2011-09-09
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 fainfy 的回复:]

你在静态方法里面调用常量 ,常量当然也应该是静态。
可是你这里不是,当然编译失败了。
[/Quote]

如果我把bx改成静态的也是一样的结果
chenchengamao 2011-09-09
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 bijanen19861113 的回复:]

引用 8 楼 chenchengamao 的回复:

引用 7 楼 skyparty 的回复:

发现bx在-128~127之间的时候,make()编译能通过
其他数值都会报损失精度
猜测原因
在类中,因为 public final int bx = 20; 是一个常量,编译期就已经确定他的值了
所以当bx的范围在byte范围中时,make()就不会报错
而byte b = o……
[/Quote]


“this.bx跟obj.bx是一个性质的吧,所以报错啊。而byte b = bx;已经直接知道了bx的类型..”

这句话怎么说 this和obj引用是一个性质?
fainfy 2011-09-09
  • 打赏
  • 举报
回复
你在静态方法里面调用常量 ,常量当然也应该是静态。
可是你这里不是,当然编译失败了。
fainfy 2011-09-09
  • 打赏
  • 举报
回复
[Quote=引用楼主 chenchengamao 的回复:]
Java code

public class MyJava {
public final int bx = 20;

public static void main(String[] args) {
MyJava obj = new MyJava();
obj.make();
byte b = obj.bx; ……
[/Quote]

大哥,你两个星怎么来的啊?
public static final int bx = 20;
chenchengamao 2011-09-09
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 beiyangxiao 的回复:]

答案是这样的:
在编译的时候,如果能确定赋值时不会损失精确度,就不会报错;如果确定会损失精确度或者不能确定是否损失精确度(非静态方式调用),都会报错。
你把bx的值改成2000,第二个地方同样会报错。
[/Quote]


你的非静态方式调用是什么?能不能举个例子,谢谢
bijanen19861113 2011-09-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 chenchengamao 的回复:]

引用 7 楼 skyparty 的回复:

发现bx在-128~127之间的时候,make()编译能通过
其他数值都会报损失精度
猜测原因
在类中,因为 public final int bx = 20; 是一个常量,编译期就已经确定他的值了
所以当bx的范围在byte范围中时,make()就不会报错
而byte b = obj.bx;在类的外部,编译器,不知道obj.bx是什么,……
[/Quote]

his.bx跟obj.bx是一个性质的吧,所以报错啊。而byte b = bx;已经直接知道了bx的类型..
beiyangxiao 2011-09-09
  • 打赏
  • 举报
回复
答案是这样的:
在编译的时候,如果能确定赋值时不会损失精确度,就不会报错;如果确定会损失精确度或者不能确定是否损失精确度(非静态方式调用),都会报错。
你把bx的值改成2000,第二个地方同样会报错。
Java_sun_888 2011-09-09
  • 打赏
  • 举报
回复
[Quote=引用楼主 chenchengamao 的回复:]
Java code

public class MyJava {
public final int bx = 20;

public static void main(String[] args) {
MyJava obj = new MyJava();
obj.make();
byte b = obj.bx; // 这里报错是因为bx不是静态的,在静态的方法里不能引用非静态 ……
[/Quote]
aotian16 2011-09-09
  • 打赏
  • 举报
回复
这么神奇?
来学习下
chenchengamao 2011-09-09
  • 打赏
  • 举报
回复
大师啊,有哪位大师快快现身吧
加载更多回复(9)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧