java.lang.Boolean源码研究

转载 2004年07月04日 20:13:00

http://blog.csdn.net/asklxf/archive/2004/06/23/23589.aspx

 

闲来无事,开始研究JDK源码(jdk 1.5 b2),先找了一个最简单的java.lang.Boolean开始解剖。

由于水平有限,难免有不少错误,还请大家指正!

首先我们剔除所有的方法和静态变量,Boolean的核心代码如下:

public final class Boolean implements java.io.Serializable,Comparable
{
    private final boolean value;
}

很明显,凡是成员变量都是final类型的,一定是immutable class,这个Boolean和String一样,一旦构造函数执行完毕,实例的状态就不能再改变了。

Boolean的构造函数有两个:

public Boolean(boolean value) {
    this.value = value;
}
public Boolean(String s) {
    this(toBoolean(s));
}

都很简单就不多说了。

另外注意到Boolean类实际上只有两种不同状态的实例:一个包装true,一个包装false,Boolean又是immutable class,所以在内存中相同状态的Boolean实例完全可以共享,不必用new创建很多实例。因此Boolean class还提供两个静态变量:

public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

这两个变量在Class Loader装载时就被实例化,并且申明为final,不能再指向其他实例。

提供这两个静态变量是为了让开发者直接使用这两个变量而不是每次都new一个Boolean,这样既节省内存又避免了创建一个新实例的时间开销。

因此,用
    Boolean b = Boolean.TRUE;

    Boolean b = new Boolean(true);
要好得多。

如果遇到下面的情况:
    Boolean b = new Boolean(var);
一定要根据一个boolean变量来创建Boolean实例怎么办?

推荐你使用Boolean提供的静态工厂方法:
    Boolean b = Boolean.valueOf(var);
这样就可以避免创建新的实例,不信看看valueOf()静态方法:

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}

这个静态工厂方法返回的仍然是两个静态变量TRUE和FALSE之一,而不是new一个Boolean出来。虽然Boolean非常简单,占用的内存也很少,但是一个复杂的类用new创建实例的开销可能非常大,而且,使用工厂方法可以方便的实现缓存实例,这对客户端是透明的。所以,能用工厂方法就不要用new。

和Boolean只有两种状态不同,Integer也是immutable class,但是状态上亿种,不可能用静态实例缓存所有状态。不过,SUN的工程师还是作了一点优化,Integer类缓存了-128到127这256个状态的Integer,如果使用Integer.valueOf(int i),传入的int范围正好在此内,就返回静态实例。

hashCode()方法很奇怪,两种Boolean的hash code分别是1231和1237。估计写Boolean.java的人对这两个数字有特别偏好:

public int hashCode() {
    return value ? 1231 : 1237;
}

equals()方法也很简单,只有Boolean类型的Object并且value相等才返true:

public boolean equals(Object obj) {
    if (obj instanceof Boolean) {
        return value == ((Boolean)obj).booleanValue();
    }
    return false;
}

顺便提一句:很多人写equals()总是在第一行写:
   if (obj==null) return false;
其实完全没有必要,因为如果obj==null,下一行的
    if (obj instanceof Type)
就肯定返回false,因为(null instanceof AnyType) = false。
详细内容请参考《Effective Java》第7条:Obey the general contract when overriding equals。

其他的方法如toString()就更简单了,只要稍微熟悉java的程序员相信都能写出来,我就不多说了。

总结

1.如果一个类只有有限的几种状态,考虑用几个final的静态变量来表示不同状态的实例。
例如编写一个Weekday类,状态只有7个,就不要让用户写new Weekday(1),直接提供Weekday.MONDAY即可。

2.要防止用户使用new生成实例,就取消public构造函数,用户要获得静态实例的引用有两个方法:如果申明public static var就可以直接访问,比如Boolean.TRUE,
第二个方法是通过静态工厂方法:Boolean.valueOf(?)

3.如果不提供public构造函数,让用户只能通过上面的方法获得静态变量的引用,还可以大大简化equals()方法:
    public boolean equals(Object obj) {
        return this==obj;
    }
可以直接用==比较引用,绝对没有问题,而且效率最高。

4.为什么JDK的Boolean没有实现上面第3点?因为那两个static变量TRUE和FALSE是在jdk 1.2以后才有的,由于前面的版本已经把构造函数申明为public,所以为了保持客户端代码能够不修改也在后面的版本中运行,只好继续提供public构造函数。

学习java笔记,java.lang.Boolean。

开始学习java,写一些代码演示一下各个类的主要功能及函数使用方法。 基本想法,按照java源代码的包结构,建立自己的一个包结构,针对每个类编写一个演示类。 我的基础类: package tjava....
  • STK_tianwen
  • STK_tianwen
  • 2009年08月22日 15:32
  • 2909

奇怪的hibernate 的类型转换错误: java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang

程序运行一直正常, 突然发生这种情况
  • jgwei
  • jgwei
  • 2013年10月12日 16:46
  • 3980

java.lang.Boolean

java.lang.Boolean JDK1.6 源码(去掉注释) package java.lang; public final class Boolean implements java...
  • zhangda_cn
  • zhangda_cn
  • 2012年02月15日 15:35
  • 464

java.lang.Boolean源码

构造方法接受两种类型的参数,一种是boolean,另一种是Stringpublic Boolean(boolean value) { this.value = value; }//传入的s若为...
  • anjingwunai
  • anjingwunai
  • 2017年07月02日 20:57
  • 82

springmvc出现返回json数据类型的错误

访问Controller出现的错误如下: java.lang.IllegalArgumentException: Unknown return value type [java.lang.Boole...
  • Love666Code
  • Love666Code
  • 2017年12月29日 17:23
  • 36

03 java.lang.Boolean

Boolean 2015.01.10 ...
  • u011039332
  • u011039332
  • 2015年08月20日 21:13
  • 296

NGUI源码分析之----UIDrawCall

NGUI源码分析之—-UIDrawCall基础知识1.在Unity中如何确定渲染的顺序相关因素: Render Queue、 ZWrite、ZTest 1.Unity会先渲染Render Queue...
  • fsgsehedhhs
  • fsgsehedhhs
  • 2017年04月14日 11:14
  • 341

【caffe源码研究】第三章:源码篇(5) :Net

简介通过合成和自动微分,网络同时定义了一个函数和其对应的梯度。通过合成各层的输出来计算这个函数,来执行给定的任务,并通过合成各层的后向传播过程来计算来自损失函数的梯度,从而学习任务。Caffe模型是端...
  • fangjin_kl
  • fangjin_kl
  • 2017年01月04日 22:02
  • 446

java.lang.Boolean学习

基础类:package tjava.testlang; import java.lang.reflect.Constructor; import java.lang.refle...
  • gengkunpeng
  • gengkunpeng
  • 2010年11月25日 20:02
  • 453

Java权限中遇到的问题汇总

一直在做ITOOJava权限,做这一部分,一上来就遇到很多的问题,这些问题因为先前没有做过,有点心有余而力不足。问题很多,大致是一上来之后,看懂了就不觉得难了。 我将错误一直记录在我的one...
  • u010540106
  • u010540106
  • 2015年08月30日 17:12
  • 1794
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java.lang.Boolean源码研究
举报原因:
原因补充:

(最多只允许输入30个字)