本文共 3654 字,大约阅读时间需要 12 分钟。
1、字符串比较 “==” 与 equals()的区别2、字符串常量是String类的匿名对象 ObjectPool3、字符串常量是不可改变的4、两种实例化的区别 匿名对象与new
5、null与String的关系
"==" 是进行数值比较,如果用在字符串对象比较上,比较的是两个对象的内存地址数值,即比较的是两个字符串是否放置在同一位置。 “equals()” 是String类中定义的方法(public boolean equals(String str)),可以用来比较字符串内容。
equals()函数还具有自动判空功能,如果参数为null,则比较结果直接返回false,如果需要判断用户输入的字符串是否为指定字符串是,一般用如下代码:
String InputStr = "Hello";//InputStr.equals("Hello"); 不使用这句,如果用户输入InputStr为空,则会出现空指向的报错。"Hello".equals(InputStr);
在引用数据类型操作中,永远都可以使用“==”进行比较,而比较的永恒是地址数值。
java源码中对String类的 equals() 方法的定义如下:可以作为日后写对象比较时 equals() 方法的参考。
/** * Compares this string to the specified object. The result is {@code * true} if and only if the argument is not {@code null} and is a {@code * String} object that represents the same sequence of characters as this * object. * * @param anObject * The object to compare this {@code String} against * * @return {@code true} if the given object represents a {@code String} * equivalent to this string, {@code false} otherwise * * @see #compareTo(String) * @see #equalsIgnoreCase(String) */ public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { // 判断是否为空,因为 null 不属于 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; }
因为字符串的频繁使用,Java的String类里面有共享设计思想。如果定义字符串的匿名对象,没有对象名指向此匿名对象,该对象内容不会被当做垃圾回收,会保存在Objectpool中,当有字符串再次定义为此匿名对象的内容时,可直接将字符串名指向Objectpool中的该对象内存即可。
String strA = "Hello"; //Hello 将被保存在ObjectPool中,不会被GC回收String strB = "Hello"; //此时strB直接指向 ObjectPool中的"Hello",二者地址相同 String strC = new String("Hello");System.out.println(strA == strB); // “==”用于字符串比较是,是对象名所保存的地址值的比较System.out.println(strA == strC);System.out.println(strB == strC);//输出结果://true//false//false
由于不能Java字符串不能修改,所以子Java文档中将String类对象称为不可变字符串。不可变字符串有一个优点:编译器可以让字符串共享,字符串会存放在公共的存储池中。每次给字符串变量重新赋值的时候其实是更改变量的引用,如下:
String A = "hello!" ; // A = "help!" // 不是将"hello!"所在区域重新赋值,而是新开辟空间,初始为"help!",然后更改变量A的引用,为"help!"
Java的设计者认为共享带来的高效率远远胜过字符串提取、拼接带来的低效率,因为大部分程序很少需要修改字符串,而更多的是对字符串进行比较。
匿名对象实例化: String strA = “Hello”;
构造方法实例化对象:String strB = new String(“Hello”);
匿名对象实例化时,Hello取自ObjectPool中的内容,如果内容不在ObjectPool中,则开辟空间,赋值此内容,并放入ObjectPool中,不会多次开辟内存。
new开辟字符串对象时,参数“Hello”为匿名对象(之后变为垃圾),之后new会在堆中再次开辟内存,将之前参数“Hello”保存在new开辟的内存中,有StrB指向该new开辟的内存,会产生空间浪费。构造方法实现的实例化,字符串不会自动入池(ObjectPool),但是可以收到入池(使用intern()函数)。
// intern()的使用String.intern();strA.intern();
String默认值为null,但是null却不是String类别(instanceof判断)
class People { private String name; public People() {} public People(String name) { if (name instanceof String) { this.name = name ; } else{ System.out.println("you input name is error@!"); this.name = "error name" ; } } public String getInfo(){ return this.name ; }}public class Demo { public static void main(String args[]) { People pa = new People() ; System.out.println(pa.getInfo()) ; // null People pb = new People(null) ; // you input name is error@! System.out.println(pb.getInfo()) ; // error name System.out.println(null instanceof String) ; // false }}
转载地址:http://dntii.baihongyu.com/