1:String实例(该网址类似讲解http://m.iask.sina.com.cn/b/6gEBjgQchkf.html)
String str1=new String("11"); String str2="11";此时的str1==str2 为false因为str1是保存的一个对象,并且此时并没有将“11”这个字符串放入string pool中,str2先用equals方法到string池中去找,找不到就会在堆内存中创建一个对象然后将对象放到strings pool,如果创建这个对象没有用了就会被jvm随时销毁
String str3 = new String("12"); String str4 = str3.intern();此时str3 == str4为false
因为str3指向的对象,经过intern方法将值放入字符串池中又分配了新的地址,所以这两个值是不一样的;String str5 = new String("13"); String str6 = str5.intern(); System.gc();说明:System.gc并没有认为此时str5指向的对象为垃圾对象,所以此时还能输出str5所指向的对象的值还是13(只有该对象不再被引用时才会被认为是垃圾对象,jvm触发gc有两种情况:1:没有线程运行时,2:内存不足时才会触发)
2:字符串是不可变类(可参考https://zhidao.baidu.com/question/1758363222430507468.html)
创建一个不可变类的需要满足的条件
a:将类声明为final,所以它不能被继承;
b:将所有的成员声明为私有的,这样就不允许直接访问这些成员;
c:对变量不要提供setter方法;
d:将所有可变的成员声明为final,这样只能对它们赋值一次;
e:通过构造器初始化所有成员,进行深拷贝(deep copy)
f:在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝;
3:引申的深克隆与浅克隆
说明
java对象的克隆是一种比较高深的技术,如果类的成员中包含可变引用类型,则在克隆是就需要使用深克隆,否则无法彻底的实现克隆。同时,若引用类型中是由可变的引用类型成员变量,则它也需要进行克隆;
克隆条件
a:必须实现Cloneable接口才有资格调用Object.clone()方法
b:实现Cloneable接口只是可克隆的条件之一,要可克隆,还必须重写写Object 的clone()方法c:(来自:https://blog.youkuaiyun.com/javafuns/article/details/1746509)
克隆实例一:https://www.cnblogs.com/acode/p/6306887.html
克隆实例二:https://jingyan.baidu.com/article/4853e1e557f84a1908f72673.html)
4附件
package pri.lsx.test.string;
/**学习下string的特性:来源于http://m.iask.sina.com.cn/b/6gEBjgQchkf.html
*
*引申得出下面的知识点
* 1:字符串是不可变类(可参考https://zhidao.baidu.com/question/1758363222430507468.html),下面就是创建一个不可变对象的满足的方式
* a:将类声明为final,所以它不能被继承;
b:将所有的成员声明为私有的,这样就不允许直接访问这些成员;
c:对变量不要提供setter方法;
d:将所有可变的成员声明为final,这样只能对它们赋值一次;
e:通过构造器初始化所有成员,进行深拷贝(deep copy)(深拷贝与浅拷贝可参考https://www.cnblogs.com/acode/p/6306887.html,及就是java对象的克隆是一种比较高深的技术,如果类的成员中包含可变引用类型,则在克隆是就需要使用深克隆,否则无法彻底的实现克隆。同时,若引用类型中海油可变的引用类型成员变量,则它也需要进行克隆(https://jingyan.baidu.com/article/4853e1e557f84a1908f72673.html) );
f:在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝;
* */
public class StringFeatures {
public static void main(String[] args) throws CloneNotSupportedException {
String str1=new String("11"); String str2="11";
if (str1 != str2) System.out.println("str1==str2 为false");//str1是保存的一个对象的值,str2先到strings池中去找,找不到就会在堆内存中创建一个对象然后将对象放到strings pool 中
System.out.println(str1.hashCode());System.out.println("11".hashCode());System.out.println(str2.hashCode());
String str3 = new String("12"); String str4 = str3.intern();
if (str3 != str4) System.out.println("str3 == str4为false"); //str3指向的对象,经过intern方法将值放入字符串池中又分配了新的地址,所以这两个值是不一样的;
String str5 = new String("13"); String str6 = str5.intern(); System.gc();
System.out.println(str5);// System.gc并没有认为此时str5指向的对象为垃圾对象,所以此时还能输出str5的值(只有该对象不再被引用时才会被认为是垃圾对象,jvm触发gc有两种情况:1:没有线程运行时,2:内存不足时才会触发)
String str7="14"; String str8="14";
if (str7==str8) System.out.println("str7==str8是相等的");//str8指向的对象就是在string pool中得到的,所以是同一个只。
//使用克隆方法,深克隆与浅克隆(参考:https://www.cnblogs.com/acode/p/6306887.html )
CloneClass cloneClass = new CloneClass();
cloneClass.var1 = 10;
CloneClass cloneClass1=(CloneClass)cloneClass.clone();
System.out.println("var1="+cloneClass1.var1+";vr2="+cloneClass1.var2+";var3="+cloneClass1.var3);//clone的对象里面的成员变量和new出来的对象的成员变量的值是不一样的
}
}
/**
* 克隆条件:
* a:必须实现Cloneable接口才有资格调用Object.clone()方法
* b:实现Cloneable接口只是可克隆的条件之一,要可克隆,还必须改写 Object 的clone()方法,因为Object.clone()方法是protected的,必须进行覆盖并改为public。
* c:(来自:https://blog.youkuaiyun.com/javafuns/article/details/1746509)
*克隆时注意:
* a:若克隆的对象里面的成员变量是引用其他类的对象,则该对象进行深度克隆。
* b:深克隆与浅克隆可参考(https://www.cnblogs.com/acode/p/6306887.html,https://jingyan.baidu.com/article/4853e1e557f84a1908f72673.html)
*
* 引申:
* 1:Java 虚拟机会自动初始化成员变量的默认值,下面各种类型的默认初始值。
a、布尔性的基本类型变量的默认值为 false。
b、引用类型的变量是默认值为 null。如:BigDecimal、String、Integer、Boolean等
c、数组引用类型的变量的默认值为 null。当数组变量的实例后,如果没有没有显示的为每个元素赋值,Java 就会把该数组的所有元素初始化为其相应类型的默认值。
d、整数类型(byte、short、int、long)的基本类型变量的默认值为0。
e、单精度浮点型(float)的基本类型变量的默认值为0.0f。
f、双精度浮点型(double)的基本类型变量的默认值为0.0d。
g、字符型(char)的基本类型变量的默认为 “/u0000”。
*
* 2:继承
* a:在包里面的类只能继承包里面的类,不能继承没有在包里面的类;不知道为什么
* b:不在包中的类有权继承所有的的类
*
*
* */
class CloneClass implements Cloneable{
int var1;int var2;int var3;
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}