在java中,一個java類將會編譯成一個class文件。在編譯時,java類並不知道引用類的實際內存地址,因此只能使用符號引用來代替。比如org.simple.People類引用org.simple.Tool類,在編譯時People類並不知道Tool類的實際內存地址,因此只能使用符號org.simple.Tool(假設)來表示Tool類的地址。而在類裝載器裝載People類時,此時可以通過虛擬機獲取Tool類 的實際內存地址,因此便可以既將符號org.simple.Tool替換為Tool類的實際內存地址,及直接引用地址。
總結:JVM對於直接引用和符號引用的處理是有區別的,可以看到符號引用時,JVM將使用StringBuilder來完成字符串的 添加,而直接引用時則直接使用String來完成;直接引用永遠比符號引用效率更快,但實際應用開發中不可能全用直接引用,要提高效能可以考慮按虛擬機的思維來編寫你的程序。
1.0 直接引用:
public class StringAndStringBuilder{
public static void main(String[] args){
System.out.println ("s=" + "asdfa");
}
}
2.0 符號引用:
public class StringAndStringBuilder{
public static void main(String[] args){
String s="asdfa";
System.out.println ("s=" + s);
}
}
- /**
- *
- */
- package com.bzu.csh;
- import java.util.Random;
- /**
- *
- * 項目名稱:Test1 類名稱:Test2 類描述: 創建人:admin 創建時間:2017年1月7日 下午9:41:36 修改人:admin
- * 修改時間:2017年1月7日 下午9:41:36 修改備注:
- *
- * @version
- *
- */
- class Test4 {
- public static final int i = 6 / 2;// 編譯時就處理了,即i =
- // 3;不初始化類,static代碼塊和靜態初始化塊不執行
- public static final int j = new Random().nextInt();// 運行時處理,需要初始化類,都執行
- static {
- System.out.println("static 靜態代碼塊");
- }
- {
- System.out.println("初始化塊");
- }
- }
- public class Test3 {
- /**
- * @param args
- * 2017年1月7日
- */
- public static void main(String[] args) {
- System.out.println(Test4.i);
- }
- }
只有主動調用時才初始化類
- /**
- *
- */
- package com.bzu.csh;
- import java.util.Random;
- /**
- *
- * 項目名稱:Test1 類名稱:Test2 類描述: 創建人:admin 創建時間:2017年1月7日 下午9:41:36 修改人:admin
- * 修改時間:2017年1月7日 下午9:41:36 修改備注:
- *
- * @version
- *
- */
- class Test6 {
- public static final int a = 6 / 2;// 編譯時就處理了,即i = 3
- // 3;不初始化類,static代碼塊和靜態初始化塊不執行
- public static final int b = new Random().nextInt(10);// 運行時處理,需要初始化類,都執行
- static {
- System.out.println("Test6 static 靜態代碼塊" + a + ":" + b);
- }
- {
- System.out.println("Test6 初始化塊");
- }
- }
- class Test4 extends Test6 {
- public static final int i = 6 / 2;// 編譯時就處理了,即i = 3
- // 3;不初始化類,static代碼塊和靜態初始化塊不執行
- public static final int j = new Random().nextInt(10);// 運行時處理,需要初始化類,都執行
- static {
- System.out.println("Test4 static 靜態代碼塊" + i + ":" + j);
- }
- {
- System.out.println("Test4 初始化塊");
- }
- }
- public class Test3 {
- /**
- * @param args
- * 2017年1月7日
- */
- static {
- System.out.println("Test3");
- }
- public static void main(String[] args) {
- // Test4 t = new Test4();結果如下:執行了初始化塊
- // Test3
- // Test6 static 靜態代碼塊3:9
- // Test4 static 靜態代碼塊3:0
- // Test6 初始化塊
- // Test4 初始化塊
- /***********************************************************/
- // System.out.println(Test4.j);// 這個不執行初始化塊
- // Test3
- // Test6 static 靜態代碼塊3:4
- // Test4 static 靜態代碼塊3:8
- // 8
- /***********************************************************/
- System.out.println(Test4.b);// 不會初始化Test4,因為b定義在了Test6
- // Test3
- // Test6 static 靜態代碼塊3:8
- // 8
- }
- }