JVM 02(essential)

  • 内存 :code segment(代码区 二进制代码),data segment(数据区),stack(栈),heap(堆)

静态变量(类级别)/字符串常量   数据区(基本类型,final,static)

局部变量(string s = "Hello world!";函数参数)     栈

new/动态分配内存(T t1 = new T(1);)       堆中构造(new的类成员变量)

new对象的类方法(当t1.Methodname(s)时)       运行时分配内存

 

  • 成员变量(在堆 GC;方法外部,类的内部定义的变量)、局部变量(在栈 方法结束则释放;方法或语句块内部如形式参数)
  • 常量池 (constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。

1 代码中所定义的各种基本类型(如int、long等等),对象型(如String及数组)的常量值(final)

2 以文本形式出现的符号引用,比如:类和接口的全限定名;字段的名称和描述符;方法和名称和描述符。

 

  • 代码区main方法中new T(,,,)后的分配顺序:

1 栈中分配对象t1,初始null

2 堆中分配内存给成员变量,调用构造函数(有参数则被视为局部变量,在栈中分配内存),进入构造函数给成员变量赋值

3 构造函数执行完,局部变量被释放

4 t1不再为null(不一定是物理地址,详细需要看另一篇)

 

String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true 在栈中分配,若已存在则将str2指向str1,但这种指向并不会使得改变str1时str2随之变化
//
String str1 =new String ("abc"); String str2 =new String ("abc"); System.out.println(str1==str2); // false 需要使用equals()比较类中的值 //由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。

String a = "ab";
String b = "a" + "b";
String c = "b";
String bb = "a" + c;
final String cc = "b";
String bbb = "a" +cc;
System.out.println((a == b)); //result = true
System.out.println((a == bb)); //result = false
System.out.println((a == bbb)); //result = true
//字符串常量的"+"号连接,将程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,"a" + 1经编译器优化后在class中就已经是a1
//"a" + bb无法被编译器优化,bb为字符串引用
//final cc 在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中"a" +cc 与"ab"、"a" + "b"等效
 
 
String a = "ab";
final String bb = getBB(); 
String b = "a" + bb;
System.out.println((a == b)); //result = false 
private static String getBB() { return "b";  }
 
String s = "a" + "b" + "c";String s = "abc"// 等价

String a = "a";String b = "b";String c = "c";String s = a + b + c; //等价于:

 StringBuffer temp = new StringBuffer();
 temp.append(a).append(b).append(c);
 String s = temp.toString();
 

 

1. main方法开始执行:int date = 9; 

date局部变量,基础类型,引用和值都存在栈中。

2. Test test = new Test(); 

test为对象引用,存在栈中,对象(new Test())存在堆中。

3. test.change(date); 

i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。

4. BirthDate d1= new BirthDate(7,7,1970); 

d1 为对象引用,存在栈中,对象(new BirthDate())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。 day,month,year为成员变量,它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后,d,m,y将从栈中消失。

5. main方法执行完之后,date变量,test,d1引用将从栈中消失,new Test(),new BirthDate()将等待垃圾回收。
  •  final 

修饰值 不能更改必须有赋初值、引用 不能再赋值、方法 不能重写、类 不能继承。

  • static

修饰内部类、成员变量、方法 =>只属于类。

  • static final

修饰成员变量 属于类的变量且只能赋值一次、方法 属于类的方法且不能重写、内部类 属于外部类且不能继承。

 

总结:

值,与引用类型。

变量:成员,局部。常量。

String  各种解释,所以现在1.5以上直接用StringBuilder吧!“用加号拼接字符串已经没有任何性能损失了。” 你在一行中用多个➕一次性拼接多个字符串没有性能损失,但是你用一个循环一个个➕字符串还是一样的性能损失。

static final 

posted on 2017-10-13 00:01  satyrs  阅读(194)  评论(0编辑  收藏  举报

导航