黑馬程序員_java高級篇反射Day11

  ----------------------ASP.Net+Android+IOS開發.Net培訓、期待與您交流! --------

 

                                                黑馬程序員_java高級篇反射Day11

 

           今天是我的第50篇博客,從快樂雜談到黑馬博客記錄,都記錄着自己的成長.

 

#用反射的方法調用main函數#


知識點1: 

args[0]是傳進來的值,就是main(String[] args)中的args中的值。

String startNAME=args[0];
Method m=Class.forName(startNAME).getMethod("main",String[].class);
 

//調用invoke方法,使用指定的參數指定的對象上的基本方法。各個參數自動解包,以匹配原始的形式參數。

m.invoke(null, new Object[]{newString[]{"1"}});
 

爲什麼getMethod("main",String[].class);中後面是String[].class,因爲

Main方法原來的參數也是String[](數組),現在只不過是以類的字節碼傳進去

知識點2

invoke方法的解釋,第一個參數表示對象,null表示不需要建立對象就能直接調用的方法,不就是靜態方法嗎。如果你要調用的不是靜態方法,你需要先建立一個對象,第一個參數就是這個對象名。第二個參數是你要傳入的值,main方法我們要傳入的是一個字符數組, new String[]{"1"},這裏確實是一個字符數組沒錯,但是java爲了兼容JDK1.4有一點問題,解決的辦法。這裏不加 new Object[]有問題,因爲JDK1.5爲了兼容1.4時,當我們給他一個new String[]{"1"}時,它不把你當成是一個數組,把你當成一個參數,因爲它會打開數組newString[],所以我們給他傳一個object數組,這樣打開的第一個就是我們的對象。

m.invoke(null, new Object[]{newString[]{"1"}});

我們調用的類的main方法

public static void main(String[] args)
    {
       System.out.println(args[0]);
    }
 

#數組的反射#


知識點1,數組反射的第一個問題,我們要注意數組的維數與類型。

如下:

//維數
       int[] a=new int[3];
       int[] b=new int[4];
       int[][] c=new int[3][4];
      
       System.out.println(a.getClass()==b.getClass());
       System.out.println(b.getClass()==c.getClass());


第一個會輸出true,因爲他們調用的是同一個字節碼。第二個輸出false,他們的維數不一樣。

 

知識點2,數組賦值問題

   這裏的知識點是,int[]表示數組裏面放int,由於a數組int並不是object。,所以賦值時會出錯。但是c可以,因爲c裏面是二維數組。表示數組裏面放數組,這樣數組是object的

Object obj=a;
Object[] obj1=c;
System.out.println(a);
System.out.println(Arrays.asList(a));
System.out.println(Arrays.asList(d));
System.out.println(a.getClass());


爲什麼第一個輸出是[[I@182f0db],而第二個輸出就是[a, b, c],我們查看他的方法,發現List(Object[]),在jdk1.4中,由於List(Object[]),裏面是object數組,當我們傳入int[]時,因爲int並不是object,所以我們就按照jdk1.5的來,List(Object...),傳入可變參數對象,當我們傳入的是可變參數對象,那麼int[]就相當於一個對象。

 

知識點3,獲得數組類的值

我們可以通過以下函數來獲得數組裏面的值,我們只要傳給他一個對象。

//通過這個函數,我們可以獲得數組內的值

public static void printObject(Object obj)
    {
        Class   c= obj.getClass();
        if(c.isArray())
    {
       int len=Array.getLength(obj);
       for(int i=0;i<len;i++)
       {
           System.out.print(Array.get(obj,i));
       }
    }
        else
        {
          System.out.println(obj);  
       }
      
    }
 


如:

String[] d=new String[]{"a","b","c"};
printObject(d);


 

我們是否可以獲得數組的類型呢?對於獲得像

int[] a=new int[2];

要獲得a前面的int類型是不太可能的。只能獲得某個元素的類型

 

#看一看HashSet與ArrayList的區別#‘


HashSet中如果加入同一個對象會出現覆蓋,但ArrayList不會。

這是爲什麼呢?因爲對於數組它是一個一個順序的放進去的,但是你的

HashSet不一樣,它會檢查是否含有相同的元素,如果相同,則不能放進去,這裏檢查的只是內存地址,並不是我們所說的值。

如下:

Collection coll=new HashSet();
Reflectpoint rp=new Reflectpoint(3,3);
Reflectpoint rp1=new Reflectpoint(3,4);
Reflectpoint rp2=new Reflectpoint(3,5);
Reflectpoint rp3=new Reflectpoint(3,3);

coll.add(rp);
coll.add(rp1);
coll.add(rp2);
coll.add(rp3);
System.out.println(coll.size());


輸出的是4個,因爲他們是四個不同的對象,雖然rp與rp3的值相同。如果我們在這再添加一個coll.add(rp);現在輸出還是4,因爲rp現在並沒有被添加進去。

 

##重點:一個是hashcode到底有什麼作用?另一個是內存泄露問題##

 

Hashcode是Reflectpoint這個類中的代碼
 
public class Reflectpoint {
    int x;
    int y;
    public Reflectpoint(int x, int y){
       super();
       this.x = x;
       this.y = y;
}
}


hash每一個對象,算出來時,我們會把它放到hash表中,如當我們沒有,在Reflectpoint類中加Hashcode(選中int x,int y,右鍵,hashcode生成代碼),當我加入值相同的對象,hash表把他們放到不同的區域,所以檢測不出來,所以就放進去了,但是當我們加入hashcode時,由於可以算出,值一樣時,就加不進去了。

 

這又衍生了一個問題,就是內存泄露問題,看下面的語句。

 

內存泄露:功能已完成的對象,不釋放佔用的資源。

 

rp.x=7;
coll.remove(rp);


如果我們將rp.x=7;改了,我們再一次刪除時,hash找不到這個對象,因爲他通過hashcode算出這個對象的hash值在hash表中找不到。所以刪不了。這就導致內存泄露。

 ----------------------ASP.Net+Android+IOS開發.Net培訓、期待與您交流! --------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章