Java 常见的 30 个误区与细节!
1 在Java中,没有goto
语句。
因为大量使用goto
语句会降低程序的可读性和可维护性,所以Java语言取消了goto
的使用。
同时,为了避免程序员自行使用goto
所带来的混乱,Java语言仍将goto
定义为一个关键字,但是没有定义任何语法,故称为“保留字”。
2 true
、false
和null
在IDE中虽然以不同的颜色显示,但是并不是关键字,而是“字面常量”,就和String
类型的abc
一样。
3 定义名称时尽量避免使用$
,因为编译器在对.java文件进行编译的时候,会将”$”编译成顶层类型与底层类型的连接符。
见下例:
在编译(javac Test3.java
)这段代码的时候,编译器会报以下错误:
Test.java:12: 错误: 类重复:
com.javastack.Test.Outer.Inner class Inner{ ^
4 Unicode转义字符处理的非常早,在解析程序之前。
例如:
在程序中出现这两行代码编译报错,这两个Unicode码分别表示”换行”和”回车”。
所以,在编译器编译的时候,代码是这样的:
5 Unicode码使用16位字符编码,在Java中用char
类型来表示。
现在Unicode已经扩展到一百万个字符,超出16位限制的成为增补字符。
所有增补字符都不能用字符常量来表示。
6 当short
,byte
,char
参加运算时,结果为int
型,而非与较高的类型相同。
如果变量是byte
,short
,byte
类型,当对其赋予编译时期的常量,而该常量又没有超过变量的取值范围时,编译器就可以进行隐式的收缩转换。
这种隐式的收缩转换是安全的,因为该收缩转换只适用于变量的赋值,而不适用于方法调用语句,即不适用于方法调用时的参数传递。
(详见java中默认类型转换的小问题)
7 注意char
类型,这是一个无符号类型。
因此,char
与short
或char
与byte
之间的转换必须显示地使用类型转换。
从byte
到char
的转换为扩展收缩转换,该转换比较特殊,即先将byte
扩展转换到int
,然后再收缩到char
。
8 在整型数据间的扩展转换中,如果操作数是char
类型(无符号类型),则进行无符号扩展,扩展位为0。
如果操作数是byte
,short
或int
(有符号类型),则进行有符号扩展,扩展位为该变量的符号位。
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.Cloneable
与java.io.Serializable
接口。
数组的成员包括变量length
(隐式存在)与从Object类继承的成员。
Cloneable
与Serializable
是两个标记的接口,这两个接口中没有显式声明任何成员。
28 接口是完全抽象的设计,不能实例化。
使A用new
方式创建的借口类型,实际上是创建了一个匿名类,该匿名类实现了接口类型。
29 如果两个接口声明了相同的变量x,则当某接口同时继承这两个接口,或者某类同时实现这两个接口时,通过简单名称访问会产生编译错误。
30 如果两个接口中声明了相同名称的方法m,并且两个方法没有构成重载,则当某接口能够同时继承这两个接口,或者某类能够同时继承这两个接口时,必须存在一种方法签名,使得该签名同时为两个m方法签名的子签名,并且在方法的返回类型上,必须存在一种类型,使得该类型同时为两个m方法返回类型的可替换类型。
来源:
http://www.kawabangga.com/posts/568
版权归原作者所有,转载仅供学习使用,不用于任何商业用途,如有侵权请留言联系删除,感谢合作。
数据与算法之美
用数据解决不可能
长按扫码关注
Java 常见的 30 个误区与细节!相关推荐
- Java 常见的 30 个误区与细节
转载自 Java 常见的 30 个误区与细节 1.在Java中,没有goto语句.因为大量使用goto语句会降低程序的可读性和可维护性,所以Java语言取消了goto的使用.同时,为了避免程序员自行使 ...
- java常见_关于Java的常见误解
java常见 Java是世界上使用最广泛的语言(需要引用),每个人对此都有自己的见解. 由于它是主流,所以通常会嘲笑它,有时是对的,但有时批评并没有触及现实. 我将尝试解释我最喜欢的5个关于Java的 ...
- Java常见的加密解密
Java常见的加密解密 不可逆加密 介绍 应用场景 一致性验证 MD5 可以为文件传输场景中,提供文件的一致性验证. 例如,文件服务器预先提供一个 MD5 校验值,用户下载完文件以后,用 MD5 算法 ...
- Java实现CRM项目过程中的细节记录(一)
CRM项目实现过程中的细节记录(一) 文章目录 CRM项目实现过程中的细节记录(一) 一.数据库相关细节 1. 表名 2. 表字段说明 3. 不使用主外键约束 4. 不使用主键自动增长 UUID 5. ...
- Java常见知识点汇总
Java常见知识点汇总 基础概念与常识 1.Java 语言有哪些特点? 2.JVM vs JDK vs JRE 3.什么是字节码?采用字节码的好处是什么? 4.为什么不全部使用 AOT 呢? 5.为什 ...
- 绩效管理常见的7大误区,越用企业越走下坡路!
绩效管理是企业中非常重要的一个环节,但是很多企业在实施过程中常常会犯一些误区,导致绩效管理的实际效果和预期效果相差甚远.下面我们一起来看看企业中常见的七个绩效管理误区. 1.公司战略和绩效没有关联 绩 ...
- Java常见数据结构以及特点、使用场景
Java常见数据结构以及特点 Java中常见的数据结构,主要分为Collection和Map两种主要接口,程序中的数据结构是继承这些接口的数据结构类. Collection接口: List 接口继承: ...
- Java常见的面试算法题:实现两个线程交替打印1到100的数
Java常见的面试算法题:实现两个线程交替打印1到100的数 思路: 这是涉及到多个线程打印的问题,一定会用到锁的(synchronized),故这就是一个多线程打印的典型案例. 代码实现: pack ...
- java常见对象_Java/10_Java常见对象.md at master · DuHouAn/Java · GitHub
Java常见对象 Arrays Arrays:针对数组进行操作的工具类. Arrays的常用成员方法: public static String toString(int[] a) //把数组转成字符 ...
最新文章
- linux 检查 文件末尾 是否有空行
- 数据结构第二章线性表学习笔记
- 测试常用shell语句——数值,数组类型;函数创建
- 推荐九种天然食物脑黄金
- redis抽奖并发_Redis优化高并发下的秒杀性能
- 龙芯发布.NET 6.0.100开发者内测版
- 转:pysqlite笔记
- Silverlight4中右键菜单实现-附源码下载
- 【Flink】Pending record count must be zero at this point : 1
- [NOIP2014] 寻找道路
- java某个参数值设置为空_@PathVariable为空时指定默认值的操作
- IOS微信API异常:unrecognized selector sent to instance 0x17005c9b0‘
- Wireshark实战分析之ARP协议(二)
- 抓包教程_最简单的Wireshark抓包TCP/UDP新手5步教程(宽带故障运维必备)
- 跪求一个中国地图矢量图。
- 驱动ST7789 240*240 TFT屏 制作分光棱镜显示要点总结(镜像后图片颜色R、B对调了,使用PS修改图片)
- 王者荣耀李白王昭君情侣头像故事: “风雨如晦,鸡鸣不已。既见君子,云胡不喜。”...
- java错误找不到符号怎么办_java错误找不到符号
- RTKlib相对定位源码解析: udstate函数
- 〖Python WEB 自动化测试实战篇⑧〗- 实战 - 利用 selenium 处理弹出框
热门文章
- C#规范整理·资源管理和序列化
- 联手微软,Docker公司将推出Docker Desktop for WSL 2
- 直播预告 - 微软MVP为你揭秘Visual Studio 2019新特性
- EFCore Lazy Loading + Inheritance = 干净的数据表 (一)
- Asp.NetCore轻松学-部署到 IIS 进行托管
- .NET Core实战项目之CMS 第十七章 CMS网站系统的部署
- 选择IT事业,意味着终身学习
- Entity Framework Core 2.0 使用代码进行自动迁移
- SIMD via C#
- 微软企业应用开发三大方向:跨平台、开放/开源与DevOps