大数据培训新三板挂牌机构 股票代码:837906 | EN CN
Java是什么?
Java历史
Java语言特点
C++ VS Java比较
Java工厂设计模式
Java抽象工厂模式
Java单例模式
Java建造者(Builder)模式
Java原型模式
Java适配器模式
Java桥接模式
Java获取网络文件大小
Java套接字到单一的客户端
Java连接套接字
Java URL部分
Java URL连接日期
Java下载网页
Java主机指定IP地址
Java确定本地IP地址
Java检查端口占用
Java查找代理服务器设置
Java创建Socket
Java线程实例
Java检查线程活着
Java如何检查一个线程停止或没有?
Java解决死锁实例
Java如何获取正在运行的线程的优先级?
Java如何监视线程的状态?
Java获取线程名称
Java线程生产者消费者问题
Java如何设置线程的优先级?
Java如何停止线程一会儿?
Java如何暂停线程?
Java获取线程ID
Java如何检查线程的优先级?
Java显示所有正在运行的线程?
Java显示线程状态
Java中断一个线程
Java Applet实例
Java创建Applet
Java使用Applet创建横幅
Java使用Applet显示时钟?
Java在一个Applet创建不同形状
Java如何使用Applet填充形状的颜色?
Java使用Applet跳转到一个链接
Java在Applet创建事件监听器
Java使用Applet显示图像
Java使用Applet在新窗口中打开链接
Java使用Applet播放声音?
Java使用Applet读取文件
Java使用Applet写入文件
Java中Swing应用程序applet
Java简单的图形用户界面-GUI
Java以不同的字体显示文本
Java使用GUI画一条线
Java创建框架-frame
Java使用GUI显示多边形
Java在矩形中显示文本
Java GUI显示不同形状
Java如何绘制GUI实心矩形?
Java创建GUI透明光标
Java检查GUI平滑处理状态
Java在框架中显示颜色
Java GUI显示饼图
Java使用图形用户界面绘制文本
Java编辑表-table
Java 使用prepared语句
Java使用保存点和回滚
Java同时执行数据库多个SQL命令
Java使用行方法
Java使用列方法
Java正则表达式实例
Java将字符串分割
Java搜索重复单词
Java查找出现的单词
Java最后一个词的索引
Java模式匹配
Java删除空格
Java匹配电话号码
Java计数组词
Java搜索词组
Java拆分正则表达式
Java替换第一个出现字符串
Java检查日期格式
Java验证电子邮件地址格式
Java替换所有匹配字符串
Java使每个单词的第一个字母大写
从XML创建SqlSessionFactory实例
不使用XML来创建SqlSessionFactory
从SqlSessionFactory获取SqlSession
映射SQL语句
作用域和生命周期
Mapper XML配置
properties元素
Settings元素
typeAliases 元素
typeHandlers元素
理解CacheLine与写出更好的JAVA
Java核心技术点之动态代理
更好的使用JAVA线程池
理解Java中字符流与字节流的区别
深入分析Java方法反射的实现原理
关于Java面试,你应该准备这些知识点
Java内存模型
2017年你不能错过的Java类库
Leakcanary Square的一款Android/Java内存泄漏检测工具
Java Synchronised机制
Java核心技术点之注解
JVM(8):JVM知识点总览-高级Java工程师面试必备
JVM(3):Java GC算法 垃圾收集器
JVM(1):Java 类的加载机制
解决ActiveMQ中,Java与C++交互中文乱码问题
关于Java Collections的几个常见问题
Java I/O 总结
JVM源码分析之Java对象的创建过程
JVM源码分析之Java类的加载过程
Java GC的那些事(下)
Java GC的那些事(上)
java对象头的HotSpot实现分析
面试的角度诠释Java工程师(一)
面试的角度诠释Java工程师(二)
框架开发之Java注解的妙用
谈谈Java反射机制
Java并发:volatile内存可见性和指令重排
死磕Java并发:Java内存模型之happens-before
死磕Java并发:深入分析volatile的实现原理
死磕Java并发:深入分析synchronized的实现原理
Java 10 可能对 Lambda 表达式进行升级
G1垃圾回收器中的字符串去重(Java 8 Update 20)
Java RESTful框架的性能比较
理解RxJava的线程模型
继续了解Java的纤程库 – Quasar
Java中的纤程库 – Quasar
Java豆瓣电影爬虫——抓取电影详情和电影短评数据
Java集合框架源码剖析:LinkedHashSet 和 LinkedHashMap
Java Lambda表达式初探
Java中的陷阱题
Java 9的这一基本功能,你可能从未听过
关于Java并发编程的总结和思考
几种简单的负载均衡算法及其Java代码实现
JAVA虚拟机关闭钩子(Shutdown Hook)
Java 脚本化编程指南
Java Scripting API 使用示例
Java 8 的 Nashorn 脚本引擎教程
如何开始使用 Java 机器学习
CognitiveJ —— Java 的图像分析库
Java 性能优化的五大技巧
Java 解惑:Comparable 和 Comparator 的区别
Google Java编程风格指南
java NIO详解
Java 异常处理的误区和经验总结
Java语法糖(4):内部类
Java语法糖(3):泛型
Java语法糖(2):自动装箱和自动拆箱
Java消息队列任务的平滑关闭
Java语法糖(1):可变长度参数以及foreach循环原理
2016最流行的Java EE服务器
自己写一个java.lang.reflect.Proxy代理的实现
java 如何在pdf中生成表格
如何防止单例模式被JAVA反射攻击
java虚拟机 jvm 局部变量表实战
聊聊并发-Java中的Copy-On-Write容器
java.lang.Instrument 代理Agent使用
Java开发者需要了解的移动开发编程语言
13个不容错过的Java项目
2016年7款最佳 Java 框架推荐
Java 开发者值得关注的 11 个技术博客
Redmonk发布Java框架流行度调研结果
Java 8开发的4大顶级技巧
GitHub漫游指南:10个值得你关注的Java项目
除了Guava,Java开发者还值得了解的5个谷歌类库
Java中创建对象的5种不同方法
Java性能优化全攻略
奇怪的Java题:为什么1000 == 1000返回为False,而100 == 100会返回为True?
11个最值得Java开发者收藏的网站
Java的常见误区与细节
对Java意义重大的7个性能指标
Java调优经验谈
关于Java并发编程的总结和思考
HDFS Federation设计动机与基本原理
《Effective STL》学习笔记(第三部分)
《Effective STL》学习笔记(第二部分)
《Effective STL》学习笔记(第一部分)
数据结构之位图
Thrift使用指南
Cassandra概要介绍
Cassandra部署与安装
Cassandra客户端
Cassandra数据模型
Cassandra中的各种策略
数据结构之树状数组
数据结构之伸展树
数据结构之后缀数组
数据结构之堆
浅析MRv1与MRv2的API兼容性
Apache Tez最新进展
运行在YARN上的计算框架
从传统操作系统角度理解Hadoop YARN

Java的常见误区与细节

于2017-05-10由小牛君创建

分享到:


1   在Java中,没有goto语句。因为大量使用goto语句会降低程序的可读性和可维护性,所以Java语言取消了goto的使用。同时,为了避免程序员自行使用goto所带来的混乱,Java语言仍将goto定义为一个关键字,但是没有定义任何语法,故称为“保留字”。

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

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

package com.laixintao.Test;

public class Outer$Inner {
	public static void main(String[] args) {
		Outer o = new Outer();
		Outer.Inner i = o.new Inner();
		i.innerPrint();
	}
}

class Outer {
	class Inner {
		void innerPrint() {
			System.out.println("Inner Print!");
		}
	}
}

在编译(javac Test3.java)这段代码的时候,编译器会报以下错误:Test.java:12: 错误: 类重复: com.laixintao.Test.Outer.Inner class Inner{ ^

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

// char c1 = 'u00a';
// char c2 = 'u00d';

在程序中出现这两行代码编译报错。这两个Unicode码分别表示”换行”和”回车”,所以,在编译器编译的时候,代码是这样的:

// char c1 = '
';
// char c2 = '
';

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方法返回类型的可替换类型。