1. 程式人生 > >java反射例項化物件

java反射例項化物件

-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);
	}
}