Java 常见的 30 个误区与细节!-阿里云开发者社区

开发者社区> 技术小能手> 正文

Java 常见的 30 个误区与细节!

简介:
+关注继续查看

1 在Java中,没有goto语句。

因为大量使用goto语句会降低程序的可读性和可维护性,所以Java语言取消了goto的使用。

同时,为了避免程序员自行使用goto所带来的混乱,Java语言仍将goto定义为一个关键字,但是没有定义任何语法,故称为“保留字”。

2 truefalsenull在IDE中虽然以不同的颜色显示,但是并不是关键字,而是“字面常量”,就和String类型的abc一样。

3 定义名称时尽量避免使用$,因为编译器在对.java文件进行编译的时候,会将”$”编译成顶层类型与底层类型的连接符。

见下例:

f92f5543f9c07a1711c72a652bcfea6cb1db67a8

在编译(javac Test3.java)这段代码的时候,编译器会报以下错误:

Test.java:12: 错误: 类重复:

com.javastack.Test.Outer.Inner class Inner{ ^

4 Unicode转义字符处理的非常早,在解析程序之前。

例如:

65f5847b7d170043972c9b36e7fae5c4fc60e214

在程序中出现这两行代码编译报错,这两个Unicode码分别表示”换行”和”回车”。

所以,在编译器编译的时候,代码是这样的:

5cacc6065e3b91bf41347dccd60d1908aa8f6087

5 Unicode码使用16位字符编码,在Java中用char类型来表示。

现在Unicode已经扩展到一百万个字符,超出16位限制的成为增补字符。

所有增补字符都不能用字符常量来表示。

6 当shortbytechar参加运算时,结果为int型,而非与较高的类型相同。

如果变量是byteshortbyte类型,当对其赋予编译时期的常量,而该常量又没有超过变量的取值范围时,编译器就可以进行隐式的收缩转换。

这种隐式的收缩转换是安全的,因为该收缩转换只适用于变量的赋值,而不适用于方法调用语句,即不适用于方法调用时的参数传递。

(详见java中默认类型转换的小问题)

7 注意char类型,这是一个无符号类型。

因此,charshortcharbyte之间的转换必须显示地使用类型转换。

bytechar的转换为扩展收缩转换,该转换比较特殊,即先将byte扩展转换到int,然后再收缩到char

8 在整型数据间的扩展转换中,如果操作数是char类型(无符号类型),则进行无符号扩展,扩展位为0。

如果操作数是byteshortint(有符号类型),则进行有符号扩展,扩展位为该变量的符号位。

9 整型数据之间的收缩转换,仅仅是截断并丢弃高位,不做任何其他处理。

10 0.1+0.2不等于0.3.System.out.println((double)0.1+(double)0.2);这条语句的输出结果是0.30000000000000004

因为计算机使用二进制来存储数据,而很多小数都不能够准确地使用二进制来表示(事实上,大多数地小数都是近似的),就像使用十进制小数不能准确地表示1/3这样地分数一样。

大多数地浮点型,在计算机中只是近似地存储其值,而不像整型那样准确地存储。

又例,这是一个死循环:for(float f = 10.1f;f != 11;f+=0.1f){}

11 float类型可以保留7~8个有效数字,而double类型可以保留15~16个有效数字,因而当int类型或long类型数值多于double或float地有效数字时,该值的一些最低有效位就会丢失,从而造成精度丢失。

这时,就会采用IEEE754最近舍入模式,提取与该整型值最接近的浮点值。

尽管整型向浮点型的转换属于扩展转换,但当数值很大或很小(绝对值很大)时,就会产生一定的精度丢失。

12 i+++j如何计算?

(这个问题在C/C++)中讨论是没有多大意义的,因为C/C++依赖于实现的硬件结构,不同的环境结果也会不同。

不过在Java中,这个结果是固定的,不受其运行的硬件环境与平台的影响)

答:根据贪心规则,前置++优于后置++,结果是(i++)+j

13 i++和++i其实都是先+1,再赋值。

++i,没什么好说的;i++,以j=i++;为例在底层的实现是:temp = i;i = i + 1; j = temp。

所以,i=15;i=i++;这个表达式的结果是15。

(因为加一之后又执行了一次赋值,从16变回15)

14 +0与-0在浮点类型变量存储中,符号位是不同的。

当-0和+0参与浮点类型的相关运算(例如相除与求余运算)时,可以产生不同的结果。

15 浮点的相除与求余运算不同与整型的相除与求余运算,当除数为0时,浮点运算不会产生ArithmeticException异常。

16 String类是非可变类,其对象一旦创建,就不可销毁。

String类那些看似修改字符序列的方法实际上都是返回新创建的String对象,而不是修改自身对象。

17 由于String对象是不可改变的,因此具有线程安全性,可以自由地实现共享。

18 在String类内部,是使用一个字符数组(char[])来维护字符序列的。

String的最大长度也就是字符数组的最大长度,理论上最大长度为int类型的最大值,即2147483647.在实际中,一般可获取的最大值小于理论最大值。

19 main()方法在表现行为上,与其他方法基本相同,可以重载,由其他方法调用,继承,隐藏,也可以抛出异常,带有类型参数。

我们也可以在一个程序中通过反射来调用main方法(或其他方法)。

20 当两个或多个方法的名称相同,而参数列表不同时,这几个方法就构成了重载。

重载方法可以根据参数列表对应的类型与参数的个数来区分。

但是,参数的名称、方法的返回类型,方法的异常列表与类型参数不能作为区分重载方法的条件。

21 究竟选择哪个方法调用,顺序是这样的:

● 在第一阶段,自动装箱(拆箱)与可变参数不予考虑,搜索对应形参类型可以匹配实参类型并且形参个数与实参个数相同的方法;
● 如果在步骤一不存在符合条件的方法,在第二阶段,自动装箱与拆箱将会执行。
● 如果在步骤二中不存在符合条件的方法,在第三阶段,可变参数的方法将会考虑。

● 如果3个阶段都没有搜索到符合条件的方法,将会产生编译错误。

如果如何条件的方法多于一个,将会选择最明确的方法。

最明确的方法定义为:如果A方法的形参列表类型对应的都可以赋值给B方法的形参列表类型,则A方法比B方法明确。

如果无法选出最明确的方法,则会产生编译错误。

22 重写和隐藏的本质区别是:重写是动态绑定的,根据运行时引用所指向对象的实际类型来决定调用相关类的成员。

而隐藏是静态绑定的,根据编译时引用的静态类型来决定调用的相关成员。

换句话说,如果子类重写了父类的方法,当父类的引用指向子类对象时,通过父类的引用调用的是子类方法。

如果子类隐藏了父类的方法(成员变量),通过父类的引用调用的仍是父类的方法(成员变量)。

23 构造器是递归调用的,子类的构造器会调用父类的构造器,直到调用Object类的构造器为止。

24 构造器没有创建对象,构造器是使用new创建对象时由系统调用的,用来初始化类的实例成员。

从顺序上说,先是创建对象,然后再调用构造器的。(构造器并没有产生新的对象)

25 默认的构造器不为空,该构造器会调用父类的无参构造器,并可能执行实例成员变量的初始化。

所以,默认的构造器至少调用了父类的构造器,它做的工作还可能更多,包括实例变量声明初始化与实例初始化块,都是在构造器中执行的。

26 当==或!=运算符的两个操作数的类型一个是基本数据类型,另一个是包装类引用类型时,将引用类型拆箱转换为基本数据类型,然后比较两个基本数据类型的值是否相等。

27 在Java中,数组也是类,数组声明的引用变量指向数组类型的对象。

所有的数组都继承Object类,并且实现了java.lang.Cloneablejava.io.Serializable接口。

数组的成员包括变量length(隐式存在)与从Object类继承的成员。

CloneableSerializable是两个标记的接口,这两个接口中没有显式声明任何成员。

28 接口是完全抽象的设计,不能实例化。

使A用new方式创建的借口类型,实际上是创建了一个匿名类,该匿名类实现了接口类型。

29 如果两个接口声明了相同的变量x,则当某接口同时继承这两个接口,或者某类同时实现这两个接口时,通过简单名称访问会产生编译错误。

30 如果两个接口中声明了相同名称的方法m,并且两个方法没有构成重载,则当某接口能够同时继承这两个接口,或者某类能够同时继承这两个接口时,必须存在一种方法签名,使得该签名同时为两个m方法签名的子签名,并且在方法的返回类型上,必须存在一种类型,使得该类型同时为两个m方法返回类型的可替换类型。


原文发布时间为:2018-08-27

本文来自云栖社区合作伙伴“数据与算法之美”,了解相关信息可以关注“数据与算法之美”。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
8359 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10160 0
常见安全组端口分享
大家好,我是华北地区某211高校计算机专业一学生,最近通过朋友推荐了解到阿里云的“飞天加速计划·高校学生在家实践”活动,一直想建立一个属于自己的个人博客,但是苦于服务器费用昂贵,很高兴能通过此活动购买到一台ECS云服务器,我现在已经开始用自己的博客来记录自己的生活了。 这里和大家分享几个阿里云安全组常见的默认端口,希望大家在放行安全组端口的时候不要出错。
322 0
Java常见面试题汇总
  动力节点Java培训最新上线Java实验班,等你来测试自己适不适合学习Java编程哦!今天的主题我们来谈谈求职,每个程序员的生涯总有几次求职经历,对于求职者而言,在面对自己心仪的公司之前总要做足成分的准备,一份全面精细的面试题可以帮助我们减少很多麻烦,为此动力节点IT培训的小编特地做了Java面试题的文章,一方面可以帮助大家巩固基础,另一方面也希望帮助苦于面试的朋友。
1046 0
Java常见面试题:多对多关系
这个多对多关系在学习Java基础的时候必须要求信手拈来,如果不熟悉,对于后面的开发来讲是不利的,对后面更深层次的理解也会出现偏差。
1732 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
11995 0
Ionic 1 & 2 开发常见问题 Q&A
原文发表于我的技术博客 本文分享了在 Ionic 1 & 2 版本开发过程中常见问题的一些 Q&A,供慕课网同学或其他朋友参考。原文发表于我的技术博客 1. 版本的问题 Ionic 2 目前属于快速迭代更新的版本,版本的更新会带来如文件结构和少许代码的变更,不过底层还是构建于 Angular 2 ...
1270 0
MySQL MHA配置常见问题
    MHA在MySQL数据库中被广泛使用,它小巧易用,功能强大,实现了基于MySQL replication架构的自手动主从故障转移,从库重定向到主库并自动同步。
1252 0
+关注
技术小能手
云栖运营小编~
7208
文章
9
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载