1. 程式人生 > >【基礎】-----反射的理解

【基礎】-----反射的理解

 建立某類A的類型別的三種方式:

1.A.class

2.A a= new A();     a.getClass();

3.Class.ForName("類的全稱");

根據類型別得到某類A的例項化

class.newInstance();

 

package com.wisdomtraffic.common;

public class ClassDemo {
  public static void main(String[] args) {
	Foo foo1=new Foo();
	//任何一個類都是Class類的例項物件,這個物件表示該類的類型別
	
	/*//第一種表示方式:*/	
	Class c1 =Foo.class; //表明任何一個類都有一個隱含的靜態成員變數class
	
	/*//第二種表示方法:通過該類的例項物件建立該類的類型別*/
	Class c2=foo1.getClass();
	
	//c1,c2表示了Foo類的類型別
	
	System.out.println(c1==c2);  //true
	
	/*//第三種表示方式:Class.ForName()*/
	Class c3=null;
	try {
		c3= Class.forName("com.wisdomtraffic.common.Foo");
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}
	System.out.println(c2==c3);  //true
	
	
	//可以通過類的類型別建立該類的物件
	try {
		Foo foo2 = (Foo)c1.newInstance();
	} catch (InstantiationException | IllegalAccessException e) {
		e.printStackTrace();
	}
  }

}
  
class Foo{}

動態載入類與靜態載入類

編譯時載入的類為靜態載入類。執行時載入的類為動態載入類

new 建立的物件時靜態載入類,編譯時就載入。若有不存在的類,在編譯時就出錯

通過動態載入類Class.ForName("類的全稱")可解決該問題

package com.wisdomtraffic.common;

public class Office {
	
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
	 //動態載入類,在執行時載入
		Class a=Class.forName(args[0]);
		//通過類型別,建立該類物件
		OfficeAble officeAble = (OfficeAble)a.newInstance();
		officeAble.start();
	}

}
package com.wisdomtraffic.common;

public interface OfficeAble {
	public void start();
}
package com.wisdomtraffic.common;

public class Word implements OfficeAble {
public void start(){
	System.out.println("word  /// ");
}
}
package com.wisdomtraffic.common;

public class Excel implements OfficeAble{

	@Override
	public void start() {
		System.out.println("Excel   ///");
		
	}

}

此時若Excel類不存在,使用Word類不會報錯

基本的資料型別及void關鍵字都存在類型別

 

抽出部分程式碼重構方法:選中程式碼,右鍵-->rafactor-->ExtractMethod

根據反射操作類中的方法

 

​
package com.wisdomtraffic.common.MyTest;

import java.lang.reflect.Method;

public class ClassDemo2 {
   public static void main(String[] args) throws Exception{
	   A a1=new A();
	   Class c1 = a1.getClass();
	   Method method = c1.getMethod("print", int.class,int.class);
	   Object invoke = method.invoke(a1, 1,2);
}
}

class A{
	public void print(int a,int b){
		System.out.println(a+b);
	}
}

​

通過反射來認識泛型的本質

        * 反射的操作都是編譯之後的操作
        * c1==c2返回true,說明編譯之後,集合的泛型是去泛型化的
        * java中集合的泛型是防止錯誤輸入的,只在編譯階段有效,繞過編譯後就失效了
        * 驗證:通過反射來操作,繞過編譯

 ArrayList a=new ArrayList();
	   ArrayList<String> a1=new ArrayList<String>();
	   a1.add("hello");
	   Class c1 = a.getClass();
	   Class c2 = a1.getClass();
	   System.out.println(c1==c2);  //true
	   /**
	    * 反射的操作都是編譯之後的操作
	    * c1==c2返回true,說明編譯之後,集合的泛型是去泛型化的
	    * java中集合的泛型是防止錯誤輸入的,只在編譯階段有效,繞過編譯後就失效了
	    * 驗證:通過反射來操作,繞過編譯
	    */
       Method m1 = c2.getMethod("add", Object.class);
       m1.invoke(a1, 20);
       System.out.println(a1.size());  //2