Integer
记录一下int和Integer之间相互比较的关系
Int和Integer
在java 5中引入了自动装箱和自动拆箱功能(boxing/unboxing),java可以根据上下文,自动进行转换,极大地简化了相关编程。javac自动把装箱转换为Integer.valueOf(),把拆箱替换为Integer.intValue()。
当我们使用 Integer integerValue = num 的时候,会自动装箱成 Integer integer = Integer.valueOf(num) ,如果num的数值小于128,则会从缓存中获取,如果大于的话会构造一个新的Integer对象(new Integer)
int与int比较
int数据类型,都是在栈内存中存储,如果这个数字在栈内存中存在就会直接指向这个内存地址,如果不存在,就会重新开辟内存空间,所以int和int类型的比较,相同的值不会存在内存不等的情况
int intValue = 234;
int intValue2 = 234;
int和Integer比较
这两个数据的相互比较,无论是谁和谁比,都最终比较的是存在栈中的值,因为int是基本数据类型,不能在对中创建数据,所以无论咋比较,都是将堆中的Integer拆箱为int类型的数据,然后进行比较
int和Integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比较
int intValue = 234;
Integer integerValue = 234;
Integer和Integer比较
当两个Integer都是new出来的时候
int1 和 int2 是通过构造函数创建的不同实例,因此它们的地址值不同。(Java9以后弃用)
Integer int1 = new Integer(42);
Integer int2 = new Integer(42);
System.out.println(int1 == int2); // false
只有一个Integer是new的
Integer integer = new Integer(42);
Integer integer1 = 42; //小于128,从缓存中获取
System.out.println(integer1 == integer); // false
都不是new的
Integer integer = 100;
Integer integer1 = 100;
System.out.println(integer1 == integer); //true,小于128,从缓存中获取
Integer integer2 = 666;
Integer integer3 = 666;
System.out.println(integer3 == integer2); //false,大于127,构造新的Integer对象
String
来自官方的一段注解,这段意思是:String 类表示字符串。 Java 程序中的所有字符串(例如“abc”)都是作为此类的实例实现的。字符串是不变的;它们的值在创建后就无法更改。字符串缓冲区支持可变字符串(StringBuffer)。因为 String 对象是不可变的,所以它们可以共享。
例如:
String str = "abc";
等价于:
char data[] = {'a', 'b', 'c'};String str = new String(data[]);
也就是,这两种方式都可以用来创建包含相同字符序列 "abc" 的字符串对象。但是其实这两种的创建方式的内部实现有所差异。
再来看一段源码:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
这段代码是String的构造函数之一,当我们new这个String的时候
String str = new String("Hello, World!");
会调用上方的构造函数,将传入的字符串作为原始字符串,并以此创建一个新的字符串对象,也就是相当于
String str1 = "Hello, World!";
String str2 = new String(str1);
换句话说,新创建的字符串是参数字符串的副本
String的赋值的两种方式
String str = new String("Hello, World!");
第一种方式:通过关键字new定义:编译程序先在字符串常量池查找,是否存在"Hello, World!"常量,如果不存在,则在字符串常量池开辟一个内存空间,存放"Hello, World!";如果存在,则不另外开辟空间,保证字符串常量区只有一个"Hello, World!",节省空间。然后在堆区,开辟一个空间,存放new出来的String对象,并在栈区开辟空间,存放变量名称str1,str1指向堆区new出来的String对象。
String str1 = "Hello, World!";
第二种方式:直接定义:在字符串常量区查找是否存在"Hello, World!"常量,如果不存在,则在字符串常量区开辟一个内存空间,存放"Hello, World!";如果存在,则不另外开辟空间;在栈区开辟空间,存放变量名称str2,str2指向字符串常量池"Hello, World!"的内存地址。
StringBuffer和StringBulider
String s1 = "a";
String s2 = "b";
String s3 = s1+s2;
String s4 = "ab";
System.out.println(s3==s4); //false
因为String是不可变的,所以s3是s1+s2使用StringBuilder的append方法进行拼接,然后通过StringBuilder的toString方法返回"ab"
//StringBuffer的私有的数组,用于toString方法(为了线程安全),StringBuilder则使用父类的value数组直接toString
private transient char[] toStringCache;
//将StringBuffer的value数组(来自父类AbstractStringBuilder),copy到toStringCache,并将使用toStringCache作为参数new一个新的String对象
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
//String对应的构造函数,传入的是数组而并非String,不会在常量池创建字符串
String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}
字符串拼接
+号拼接
String str1 = "hello";
String str2 = "world";
String result = str1 + str2;
会被编译器优化成String result = new StringBuilder().append(str1).append(str2);
常量字符串的拼接,编译器会做优化,使用String就可以:
String str = "Java" + "PHP" + "Python" + "C";
StringBuffer或者StringBuilder的append方法(supper.append)
和String的concat差不多
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count) //从strstr中复制字符到一个字符数组value,String的getChars方法内部调用System.arraycopy(native方法)
count += len;
return this;
}
String的concat方法
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
String的intern方法
当调用 String.intern() 方法时,如果常量池中不存在该字符串,它会将字符串添加到常量池中,并返回常量池中该字符串的引用。如果常量池中已经存在该字符串,它会返回常量池中的引用,而不会创建新的字符串对象。
String str1=new StringBuilder("this is ").append("a string").toString();
//执行完这行代码后,常量池中会有"this is "和"a string",但是不会有"this is a string"。
System.out.println(str1.intern()==str1);//true
String str2=new String("this is a string");
System.out.println(str2==str2.intern());//false
System.out.println(str2 == str1); //false
str1 = str1.intern();
str2 = str2.intern();
System.out.println(str1 == str2); //true
标签:String,int,str1,new,字符串,Integer
From: https://www.cnblogs.com/NorthnightX/p/17636303.html