Java的常见误区与细节

网上转来的

昨天整整一天,我都都呆在图书里。本打算找一些书学习“正则表达式”,很失望,没找到有这部分的内容的书。发现了一本《Java深入解析》,其中涉及了很多平时没有注意的一些误区,也许开发的时候用不上,但是对这些概念却不能模糊。书中的内容还是很有用处,这里摘要了一些笔记。

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

2      true、    false和    null在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!");
    }
  }
}

packagecom.laixintao.Test;

publicclassOuter$Inner{

publicstaticvoidmain(String[]args){

Outero=newOuter();

Outer.Inneri=o.newInner();

i.innerPrint();

}

}

classOuter{

classInner{

voidinnerPrint(){

System.out.println("Inner Print!");

}

}

}

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

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

Unicode编译错误

// char c1 = ‘\u00a‘;
// char c2 = ‘\u00d‘;

// char c1 = ‘\u00a‘;

// char c2 = ‘\u00d‘;

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

Unicode编译

// char c1 = ‘
‘;
// char c2 = ‘
‘;

// char c1 = ‘

‘;

// char c2 = ‘

‘                ;

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   整型数据之间的收缩转换,仅仅是截断并丢弃高位,不做任何其他处理。 1    0.1+0.2不等于0.3.System.out.println((double)0.1+(double)0.2);这条语句的输出结果是   / /http://www.pprar.com  0.30000000000000004。因为计算机使用二进制来存储数据,而很多小数都不能够准确地使用二进制来表示(事实上,大多数地小数都是近似的),就像使用十进制小数不能准确地表示1/3这样地分数一样。大多数地浮点型,在计算机中只是近似地存储其值,而不像整型那样准确地存储。又例,这是一个死循环:    for(float f = 10.1f;f != 11;f+=0.1f){}

10          float类型可以保留7~8个有效数字,而          double类型可以保留15~16个有效数字,因而当          int类型或long类型数值多于          double或          float地有效数字时,该值的一些最低有效位就会丢失,从而造成精度丢失,这时,就会采用IEEE754最近舍入模式,提取与该整型值最接近的浮点值。          尽管整型向浮点型的转换属于扩展转换,但当数值很大或很小(绝对值很大)时,就会产生一定的精度丢失。

11      i+++j如何计算?(这个问题在C/C++)中讨论是没有多大意义的,因为C/C++依赖于实现的硬件结构,不同的环境结果也会不同。不过在Java中,这个结果是固定的,不受其运行的硬件环境与平台的影响) 答:根据贪心规则,前置++优于后置++,结果是    (i++)+j

12      i++和++i其实都是先+1,再赋值。++i,没什么好说的;i++,以    j=i++;为例在底层的实现是:    temp = i;i = i + 1; j = temp; 所以,    i=15;i=i++;这个表达式的结果是15.(因为加一之后又执行了一次赋值,从16变回15)

13   +0与-0在浮点类型变量存储中,符号位是不同的。当-0和+0参与浮点类型的相关运算(例如相除与求余运算)时,可以产生不同的结果。

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

15      String类是非可变类,其对象一旦创建,就不可销毁。    String类那些看似修改字符序列的方法实际上都是返回新创建的    String对象,而不是修改自身对象。

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

17   在    String类内部,是使用一个字符数组(    char[])来维护字符序列的。    String的最大长度也就是字符数组的最大长度,理论上最大长度为int类型的最大值,即2147483647.在实际中,一般可获取的最大值小于理论最大值。

18      main()方法在表现行为上,与其他方法基本相同,可以重载,由其他方法调用,继承,隐藏,也可以抛出异常,带有类型参数。我们也可以在一个程序中通过反射来调用    main方法    (或其他方法)。 2当两个或多个方法的名称相同,而参数列表不同时,这几个方法就构成了重载。重载方法可以根据参数列表对应的类型与参数的个数来区分,但是,参数的名称、方法的返回类型,方法的异常列表与类型参数不能作为区分重载方法的条件。

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

  • 在第一阶段,自动装箱(拆箱)与可变参数不予考虑,搜索对应形参类型可以匹配实参类型并且形参个数与实参个数相同的方法;
  • 如果在步骤一不存在符合条件的方法,在第二阶段,自动装箱与拆箱将会执行。
  • 如果在步骤二中不存在符合条件的方法,在第三阶段,可变参数的方法将会考虑。
  • 如果3个阶段都没有搜索到符合条件的方法,将会产生编译错误。如果如何条件的方法多于一个,将会选择最明确的方法。最明确的方法定义为:如果A方法的形参列表类型对应的都可以赋值给B方法的形参列表类型,则A方法比B方法明确。如果无法选出最明确的方法,则会产生编译错误。

20   重写和隐藏的本质区别是:重写是动态绑定的,根据运行时引用所指向对象的实际类型来决定调用相关类的成员。而隐藏是静态绑定的,根据编译时引用的静态类型来决定调用的相关成员。换句话说,如果子类重写了父类的方法,当父类的引用指向子类对象时,通过父类的引用调用的是子类方法。如果子类隐藏了父类的方法(成员变量),通过父类的引用调用的仍是父类的方法(成员变量)。

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

22   构造器没有创建对象,构造器是使用new创建对象时由系统调用的,用来初始化类的实例成员。从顺序上说,先是创建对象,然后再调用构造器的。    (构造器并没有产生新的对象)

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

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

25   在Java中,数组也是类,数组声明的引用变量指向数组类型的对象。所有的数组都继承    Object类,并且实现了    java.lang.Cloneable与    java.io.Serializable接口。数组的成员包括变量    length(隐式存在)与从Object类继承的成员。    Cloneable与    Serializable是两个标记的接口,这两个接口中没有显式声明任何成员。

26   接口是完全抽象的设计,不能实例化。使A用    new方式创建的借口类型,实际上是创建了一个匿名类,该匿名类实现了接口类型。

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

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

时间: 2024-11-06 09:40:47

Java的常见误区与细节的相关文章

Java总结——常见Java集合实现细节(1)

Java提高--常见Java集合实现细节(1) 2018年04月18日 15:07:35 阅读数:25 集合关系图 Set和Map set代表一种集合元素无序.集合元素不可重复的集合 map代表一种由多个key-value对组成的集合 set和map的关系 set和map的接口十分类似. Map的key有一个特征:所有key不能重复,且key之间没有顺序,也就是说将所有key组合起来就是一个Set集合. Map-->Set : Map中提供了  Set<k> keySet()  返回所有

3.5星|《小学问》:年轻人思维与婚恋常见误区解析

“ 这项研究结果被管理学者形容为“懒蚂蚁效应”.意思是说,在一个机构中,一定要有一批这样的“懒蚂蚁”,不被日常事务性工作绑定,而将大部分时间用于“侦察”和“研究”,发现机构的薄弱之处,同时保持对外界环境的敏锐感知.说白了就是不遵常规.敢想敢干.#870” 小学问 作者: 黄执中 / 周玄毅 / 邱晨 / 马薇薇 / 胡渐彪 出版社: 北京联合出版公司 副标题: 解决你的7种人生焦虑 出版年: 2018-1 定价: 52 装帧: 平装 ISBN: 9787559613288 01 — 全书汇集各种

NODE.JS学习的常见误区及四大名著

NODE.JS学习的常见误区及四大名著 前段时间由于不满于社区里很多人对于NODE.JS的种种误解而写了一篇文章名为: NODE.JS之我见:http://www.cnblogs.com/pugang/p/4374681.html 收到了很多兄弟的热情回复和激烈讨论,在此深表感谢,有的朋友觉得我写的比较粗犷,没有给出具体的性能分析和对比,在此我想说的是其实好多东西的性能分析,根本就不用我写到博客上,其一是如果我写了,很多人同样会觉得不客观,不中立,其二是网上很多中立的机构,随便搜索一下,对比太多

Java中常见的5种WEB服务器介绍

这篇文章主要介绍了Java中常见的5种WEB服务器介绍,它们分别是Tomcat.Resin.JBoss.WebSphere.WebLogic,需要的朋友可以参考下 Web服务器是运行及发布Web应用的容器,只有将开发的Web项目放置到该容器中,才能使网络中的所有用户通过浏览器进行访问.开发Java Web应用所采用的服务器主要是与JSP/Servlet兼容的Web服务器,比较常用的有Tomcat.Resin.JBoss.WebSphere 和 WebLogic 等,下面将分别进行介绍. Tomc

Java基础常见英语词汇

(转自http://www.jianshu.com/p/2743fe834166) Java基础常见英语词汇(共70个) ['?bd?ekt] ['?:rientid]导向的 ['pr??ɡr?m??]编程OO: object-oriented ,面向对象 OOP: object-oriented programming,面向对象编程 [d?'vel?pm?nt][k?t]工具箱 ['v??tj??l]虚拟的JDK:Java development kit, java开发工具包 JVM:java

java中常见的输入输出流案例学习

字节输入流: 1.FileInputStream 用途:从文件系统中的文件获得输入字节,常用于读取图像.声音等原始字节流,读取字符流可考虑使用FileReader 详细构造函数与常用方法可参考API文档,网上已经有中文版的API了,我是个E文盲,伤不起 这里介绍一个最常见的方法: read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中. ->off:b字节数组中的偏移量 小知识:数组偏移量,比如a[1,2,3,4,5]

HTML5标签使用的常见误区----转载

最近组内进行HTML5标签的学习,方法呢就是大家每人挑选几个标签,自己先去学习,然后给大家作讲解.这个过程大家还是挺有收获的.但是现在HTML5还处在草案阶段,有些新的标签元素的解释也是经常有变化,甚至标签加入/移出也很频繁(比如 hgroup),同时现有的大的门户网站在使用HTML5方面也没有很好的范例可以参考,让大家的学习过程更摸索.下面是我在 html5doctor 上面看到的一篇文章,在目前大家懵懂的阶段,可能看看大师的讲解会更容易理解.由于才疏学浅,很多不明白的地方可能只是做了字面上的

影响Java代码性能的一些细节

读<Effective Java>的一些收获,会持续添加. Integer和 int的区别: int是 Java基本数据类型,表示一个整型值.Integer是对 int基本类型的一个封装(每一个 Integer对象中都包含一个"private final int value;"的成员变量),提供了一系列的通用方法,如 int与 String的相互转换,把 int值转换为 long.char等其他基本类型.相应地,两个封装了相同的 int值的 Integer对象在使用&quo

Java中常见的设计模式

我在这里稍微总结一下Java中常见的一些设计模式. 1,单例设计模式 单例设计是Java中最常见的模式之一,,它就是要保证程序里边只有一个对象实例.就好比班上都叫他为班长,是因为得保证班上只有一个班长. 单例设计模式的程序设计思想反应的是Java面向对象思想的封装特性.就是为了保证只有一个对象实例,我们私有化它的构造函数,对外只提供一些相关的 公共方法来获得对象实例. 单例设计模式的实现主要分为饿汉式和懒汉式 饿汉式是先对类的对象实例化,随着类的加载对象也加载进来缺点是会造成性能的损耗好处是实现