java中的 08x是什么?javashort怎么-1
今天给各位分享java中的 08x是什么的知识,其中也会对javashort怎么-1进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
javashort怎么-1
注:如未特别说明,Java语言规范 jls均基于JDK8,使用环境是 eclipse4.5+ win10+ JDK 8
本篇的知识点,主要是涉及到 Java中一些比较常见的默认窄化处理(Java编译器自动添加的),这里将从一个问题开始,据说这也是一道常见的笔试题/面试题:
为什么 short i= 1; i+= 1;可以正确编译运行而 short i= 1; i= i+ 1;会出现编译错误?
其他说法:都放在一起编译会出现有什么结果,哪一行报错?为什么?
笔者注:其实这其中会涉及到一些编译优化和底层的知识,限于知识面,本篇不涉及,如有需要,可自行搜索。
本文的目录结构如下:
1、结论
关于开篇提出的问题,这里先直接给出结论:
Java语言规范规定基础数据类型运算默认使用32位精度的int类型
只要是对基本类型做窄化处理的,例如 long-> int-> short-> char,都需要做强制转换,有些是Java编译器默认添加的,有的则是代码中显式做强制转换的。
short i= 1; i+= 1;可以正确编译运行是因为Java编译器自己添加了强制窄化处理,即对于任何的T a; X b; a+= b;等价于T a; X b; a=(T)(a+ b);Java编译器会默认做这个显式强制转换(尽管有时候会出现精度问题,例如 b是 float、 double类型,强烈建议不要有这样的操作)。前面的i+= 1其实就等价于i=(int)(i+ 1),即便将数字1换成是double类型的1.0D也是如此。
short i= 1; i= i+ 1;编译不通过的原因就很明显了:无论是代码中,还是Java编译器,都没有做强制转换,int类型直接赋给 short,因此编译出错。
对于常量(数字常量、常量表达式、final常量等),Java编译器同样也可以做默认的强制类型转换,只要常量在对应的数据范围内即可。
2、详解
接下来讲详细分析为什么 short i= 1; i+= 1;可以正确编译而 short i= 1; i= i+ 1;则会编译失败。先列一下搜出来的一些令人眼前一亮(or困惑)的代码
public static voidmain(String[] args){//注:short∈ [-32768, 32767]
{/** 1、对于+=,-=,*=,/=, Java编译器默认会添加强制类型转换,
*即 T a; X b; a+= b;等价于 T a; X b; a=(T)(a+ b);*/
//0是int类型的常量,且在short范围内,被Java编译器默认强制转换的
short i= 0;
i+= 1;//等价于 i=(short)(i+ 1);
System.out.println("[xin01] i="+ i);//输出结果: 1
i=(short)(i+ 1);
System.out.println("[xin02] i="+ i);//输出结果: 2
/**下面这2行都会有编译报错提示:
* Exception in thread"main" java.lang.Error: Unresolved compilation problem:
* Type mismatch: cannot convert from int to short
* [注]错误:不兼容的类型:从int转换到short可能会有损失
* Eclipse也会有提示: Type mismatch: cannot convert from int to short*/
//i= i+ 1;//i= 32768;
i= 0;
i+= 32768;//等价于 i=(short)(i+ 32768);下同
System.out.println("[xin03] i="+ i);//输出结果:-32768
i+=-32768;
System.out.println("[xin04] i="+ i);//输出结果: 0
i= 0;long j= 32768;
i+=j;
System.out.println("[xin05] i="+ i);//输出结果:-32768
i= 0;float f= 1.23F;
i+=f;
System.out.println("[xin06] i="+ i);//(小数位截断)输出结果: 1
i= 0;double d= 4.56D;
i+=d;
System.out.println("[xin07] i="+ i);//(小数位截断)输出结果: 4
i= 10;
i*= 3.14D;
System.out.println("[xin08] i="+ i);//输出结果: 31
i= 100;
i/= 2.5D;
System.out.println("[xin09] i="+ i);//输出结果: 40
}
{/** 2、常量表达式和编译器优化:常量折叠*/
//2* 16383= 32766//(-2)* 16384=-32768//都在 short范围内,常量表达式在编译优化后直接用对应的常量结果,然后编译器做强制转换
short i= 2* 16383;//等价于 short i=(short)(2* 16383);
short j=(-2)* 16384;//2* 16384= 32768,超过 short范围,编译器不会做转换//Type mismatch: cannot convert from int to short//short k= 2* 16384;//常量表达式在编译优化后直接用对应的常量结果,然后编译器做强制转换
short cThirty= 3* 10;short three= 3;short ten= 10;//Type mismatch: cannot convert from int to short//short thirty= three* ten;
final short fTthree= 3;final short fTen= 10;//常量表达式在编译优化后直接用对应的常量结果,然后编译器做强制转换
short fThirty= fTthree*fTen;final short a= 16384;final short b= 16383;//常量表达式在编译优化后直接用对应的常量结果,然后编译器做强制转换
short c= a+b;
}
}
接下来根据代码罗列的两部分分别进行说明:
2.1、对于+=,-=,*=,/=, Java编译器默认会添加强制类型转换,即 T a; X b; a+= b;等价于 T a; X b; a=(T)(a+ b);
A compound assignment expression of the formE1 op= E2is equivalent toE1=(T)((E1) op(E2)), whereTis the type ofE1, except thatE1is evaluated only once.
For example, the following code is correct:
short x= 3;
x+= 4.6;
and results in x having the value 7 because it is equivalent to:
short x= 3;
x=(short)(x+ 4.6);
笔者注:
实际上,直接加上强制类型转换的写法,也是大家都熟悉且理解起来最清晰的方式,可以避免可能潜在的类型不匹配时出现的精度损失问题,使用的时候需要注意。当然,笔者认为这些方式都没有好坏之分,正确地使用即可。
Java从语言规范层面对此做了限制。有兴趣的还可以通过 class文件和 javap-c反汇编对所使用的字节码作进一步的研究。
知道了Java语言相关的规范约定,我们就可以看出,与之对应的是以下这种出现编译错误的写法(报错提示:Type mismatch: cannot convert from int to short):
short i= 1;//i+ 1是 int类型,需要强制向下类型转换
i= i+ 1;
2.2、常量表达式和编译器优化:常量折叠
需要注意的是,前面的示例short x= 3;中的3其实默认是 int类型,但是却可以赋值给short类型的x。这里涉及到到的其实是常量表达式。
In addition, if the expression is a constant expression(
A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.
A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
Byte and the value of the constant expression is representable in the type byte.
Short and the value of the constant expression is representable in the type short.
Character and the value of the constant expression is representable in the type char.
对于常量表达式,其结果是可以自动做窄化处理的,只要是在对应的数据类型范围内,Java编译器就进行做默认强制类型转换。
Some expressions have a value that can be determined at compile time. These are constant expressions(
true(short)(1*2*3*4*5*6)
Integer.MAX_VALUE/ 2
2.0*Math.PI"The integer"+ Long.MAX_VALUE+" is mighty big."
A constant variable is a final variable of primitive type or type String that is initialized with a constant expression(
通过常量表达式赋值的final变量都是常量,这种也是编译期可以确认最终值,会通过编译优化直接赋予最终值,而且可以直接依靠编译器做窄化处理。
对于这一块,其实对应的是一个比较基础的编译器优化:常量折叠(Constant Folding),有兴趣的可以自行搜索。stackoverflow上由相关的讨论,参考[9]、[10]、[11]
笔者注:
尽管常量表达式最终都被编译器优化为直接值,但是为了清晰,提高可读性、可维护性,代码中没必要对常量直接换算,例如一天 24* 60* 60秒,其实可以分别用可读性更强的final常量来表示。
Bloch大神的 Java Puzzlers中也有相关的一些说明,有兴趣的可以去看看
“*”,这个符号是什么意思
*是乘。
星形标示号*通常置于有关的词句的左上角或右上角,作为划分文章不同部分的符号成组使用时单独占一行。在电脑中,由于“×”容易和未知数x混淆,所以使用*来代替乘号。
扩展资料:
*的其它作用
1、它通常用来做注释符号。
2、用来表示密码,以体现出已输入的字符数量,同时可以避免输入的密码被人看到。
3、也表示某些词语或字无法显示,或不符合词语审查,如具有色情、反动等敏感词会用此符号来屏蔽。
4、用来表示C语言中的指针声明符。
5、如果用于在数学里面的话,相当于一个乘号(/用于分隔而且相当\于除号(÷))
6、SQL中select*表示输出结果里包含表里的全部字段。
7、ascii值为42。
参考资料来源:百度百科-*
! 这个符号是什么意思。
这是叹号,也叫感叹号,用于句子结尾,表示惊叹、感叹或号叹。《标点符号用法》中也指出“感叹句末尾的停顿,用叹号。”“语气强烈的祈使句末尾,也用叹号。”“语气强烈的反问句末尾,也用叹号。”
一般认为“!”这一符号源自欧洲中世纪,于印刷术之前的专职工作[复写员],专为私人或公共事务手工抄写文件,用于标注惊喜和喜悦的句尾[io],拉丁语的“io”原意为[万岁]欢呼的意思。在时间的演变下i停留在o的上方,成为今日的叹号。
扩展资料:
感叹号的用法
1、天涯若比邻,海内存知己,天涯问答的朋友真多呀!
2、僧多粥少,现在的话费真难赚啊!
3、中国的万里长城真雄伟啊!
4、愿我们的祖国更加壮大、更加辉煌!
5、往日,您在我的心田播下了知识的种子,今天,才有我在科研中结出的硕果——老师,这是您的丰收!
好了,文章到这里就结束啦,如果本次分享的java中的 08x是什么和javashort怎么-1问题对您有所帮助,还望关注下本站哦!