码迷,mamicode.com
首页 > 编程语言 > 详细

java.lang(String)

时间:2017-08-27 00:15:00      阅读:263      评论:0      收藏:0      [点我收藏+]

标签:cep   数组   private   nat   bounds   except   构造函数   fbo   sed   

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

    /** The value is used for character storage. */
    private final char value[];

    private int hash; // Default to 0

    public String() { //无参构造器
        this.value = new char[0];
    }

    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

/*****传入一个字符数组的构造函数,使用java.utils包中的Arrays类复制******/
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }

/*******传入一个字符串数字,和开始元素,元素个数的构造函数******/
    public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBoundsException(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }
/*********************类似方法不介绍了**************************/

    public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

/***********s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]*********/
    public int hashCode() {
        int h = hash;
/***如果hash没有被计算过,并且字符串不为空,则进行hashCode计算*****/
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }    
/***intern方法是Native调用,它的作用是在方法区中的常量池里通过equals方法寻找等值的对象,如果没有找到则在常量池中
开辟一片空间存放字符串并返回该对应String的引用,否则直接返回常量池中已存在String对象的引用。*****/ public native String intern();

举例:

String a = "abc";
String b = new String("ab1").intern();
if ( a == b ) {
  System.out.println("a == b");  
} else {
  System.out.println("a不等于b");
}
打印出:a == b

1. 什么是不可变类

所谓不可变类,就是创建该类的实例后,该实例的属性是不可改变的,Java提供的包装类和java.lang.String类都是不可变类。当创建它们的实例后,其实例的属性是不可改变的。

需要注意的是,对于如下代码

String s="abc";
s="def";

你可能会感到疑惑,不是说String是不可变类吗,这怎么可以改变呢,平常我也是这样用的啊。请注意,s是字符串对象的”abc”引用,即引用是可以变化的,跟对象实例的属性变化没有什么关系,这点请注意区分。

2.String类被设计成不可变的原因

  1. 字符串常量池的需要
  2. 允许String对象缓存HashCode

    Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。

    字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必每次都去计算新的哈希码.

  3. 安全性:String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要的String参数等, 假若String不是固定不变的,将会引起各种安全隐患。 

  4. 线程安全:因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。

3. 如何实现一个不可变类

既然不可变类有这么多优势,那么我们借鉴String类的设计,自己实现一个不可变类。 
不可变类的设计通常要遵循以下几个原则:

    1. 将类声明为final,所以它不能被继承。
    2. 将所有的成员声明为私有的,这样就不允许直接访问这些成员。
    3. 对变量不要提供setter方法。
    4. 将所有可变的成员声明为final,这样只能对它们赋值一次。
    5. 通过构造器初始化所有成员,进行深拷贝(deep copy)。
    6. 在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝。

java.lang(String)

标签:cep   数组   private   nat   bounds   except   构造函数   fbo   sed   

原文地址:http://www.cnblogs.com/myseries/p/7436731.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!