JVM
方法区:
类变量,类信息,方法信息,常量池(符号引用,以常量池表的形式)
常量池:
1、constant_utf8 :保存字符串的unicode编码。
Integer t1 = 127;
Integer t2 = 127;
t1 == t2; return true;
Integer t1 = 128;
Integer t2 = 128;
t1 == t2; return false;
为什么呢? 因为 int 类型的字面值(-128-127)的值放在这个表里: CONSTANT_integer 3
1、Java中 == 是用来比地址的除了基本数据类型外。
2、equals默认与==一样也就是说从object对象里继承过来的方法默认比地址。
3、在Java中所有对象的超类就是Object。
超类: 就是父类。
Object中的方法:
private static native void registerNatives();
方法中有一个 native 关键字。
native:
在Java中方法修饰符native表示这个方法是通过JNI来调用C语言或者C++来执行的。
把C语言的代码添加到本地方法栈中去执行。
public boolean equals(Object obj) {
return (this == obj);
}
equals默认是 == 对比。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
默认的toString() 是类名+@+hashCode值。
System.out.println(new Test()); 打印方法 会自动执行toString();
通过源码及注释:
我们知道,在Java中万物皆对象,对象他爹他爷爷就是Object类。
线程栈和本地方法栈:
线程栈:用于执行Java方法。
本地方法栈:用于执行C或者C++方法。
面试题:
String string1 = "main";
String string2 = "main";
String string3 = new String("main");
为什么s1==s2==true ,s1==s3 ==false???
因为s1和s2 创建的对象保存在常量池中的String常量表,中有一个index,索引会指向utf8常量表中的"main"字符串。
而new String 会先实例化在堆内存中,之后指向utf8常量表,虽然值相同,但是内存地址不同。
一个堆内存地址,一个方法区常量表内存地址。
如果"hello" 这个字面值在前面已经出现过,那么只创建了一个对象。
如果没有出现过。那么创建了两个对象。
String的intern()方法返回是 常量池里面字面值的地址,如果常量池里面没有这个字面值,那么先把这个字面值放到放量表
里面之后,返回常量表的地址。