java反射例項化物件
阿新 • • 發佈:2018-12-23
-Class類
Java中手動建立的每一個類,在編譯後JVM都會為其建立一個Class類物件,在這個Class類物件中儲存了所建類的資訊。
可通過Class類提供的方法為一個類例項化物件,區別與new關鍵字建立物件,前者是在類已經編譯好的情況下,通過指定類名來建立例項化物件,後者是在編譯之後之間建立例項化物件。
也可通過Class類在執行時獲得某個類物件的資訊。
下面是獲取Class類物件的三種方法。
package org.test; /** * @ClassName: TestDemo * @Description: 獲取Class類物件的三種方法 * @author 王逍遙 * @date 2018-6-8 下午1:13:56 */ class Person{} public class TestDemo { public static void main(String args[]) throws ClassNotFoundException{ Person per = new Person(); /* * getClass()取得Person的Class類物件,Object類提供此方法 * 看原始碼可知getClass()返回的是Class<?>,per.getClass()取得的就是Person類的Class類物件 * */ System.out.println(per.getClass().getName()); //輸出Class類物件中Person類的資訊 Class<?> cls = Person.class; //Person.class,取得Person類的Class類物件 System.out.println(cls.getName()); //輸出Class類物件中Person類的資訊 Object obj = Class.forName("org.test.Person"); System.out.println(obj.getClass().getName()); Class<?> cls2 = Class.forName("org.test.Person"); //forName通過全限定名獲取Class類物件 System.out.println(cls2.getName()); //輸出Class類物件中Person類的資訊 } }
通過反射例項化物件:
package org.test; /** * @ClassName: TestDemo02 * @Description: 反射例項化物件 * @author 王逍遙 * @date 2018-6-8 下午1:13:56 */ class Person { public Person() { System.out.println("**************"); //由這個輸出可知,反射例項化物件也要呼叫構造方法 } } public class TestDemo { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{ Class<?> cls = Class.forName("org.test.Person"); //通過類全限定名獲取Person的Class類物件 Person per = (Person) cls.newInstance(); // newInstance()例項化物件 System.out.println(per); } }
newInstance()在執行時例項化物件,關於執行時這一點,可以參考工廠模式與反射的結合,即只需要更改主方法中的類全限定名引數,就可以增加例項化物件。
-總結
Java可以通過反射機制來例項化一個物件,也可用反射呼叫構造方法,指定構造方法引數,另外還有反射呼叫方法、屬性等。反射加強了Java的配置性和擴充套件性(比如反射與工廠模式的集合),Spring框架提供的許多功能都是Java反射來實現,SpringIoC就是。
另外疑問ssm框架中許多可寫在Java程式碼中的內容都用*.xml來代替,這是否也與反射相關呢?
補上反射呼叫構造方法,方法的程式碼:
package org.test; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * @ClassName: Temp * @Description: 反射呼叫構造方法 * @author 王逍遙 * @date 2018-6-11 上午8:34:07 */ class Person(){ private String name; private int age; public Person(){} public Person(String name, int age) { this.name = name ; this.age = age ; System.out.println("------------------"); } public String toString() { return "姓名:" + this.name + ",年齡:" + this.age; } } public class Temp { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { Class<?> cls = Class.forName("org.test.Person"); //建立per物件,無參 Person per = (Person) cls.newInstance(); System.out.println(per); //構造引數建立物件,新增引數 Constructor<?> cons=null; cons=cls.getConstructor(String.class,int.class);//獲取指定引數的構造方法 Person per2 = (Person) cons.newInstance("hehe",3);//建立新物件時呼叫構造方法 System.out.println(per2); } }
package org.test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @ClassName: ReflectDemo03
* @Description: 反射呼叫普通方法
* @author 王逍遙
* @date 2018-6-11 上午8:47:15
*/
class Person{
//無參無返回值
public void test(){
System.out.println("heiheiheihei");
}
//有參無返回值
public void test02(String temp){
System.out.println(temp);
}
//有參有返回值
public String test03(String temp){
return temp;
}
}
public class ReflectDemo03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<?> cls=Class.forName("org.test.Person");
//提供一個統一的物件來呼叫方法
Object obj = cls.newInstance();
//無參無返回值
Method met = cls.getMethod("test");
met.invoke(obj);
//有參無返回值
Method met2 = cls.getMethod("test02", String.class);
met2.invoke(obj, "hehehehehe");
//有參有返回值
Method met3 = cls.getMethod("test03", String.class);
//用re來接收返回的內容
Object re = met3.invoke(obj, "hahahahaha");
System.out.println(re);
}
}