----------------------ASP.Net+Android+IOS開發.Net培訓、期待與您交流! --------
今天是我的第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培訓、期待與您交流! --------