- 獲取運行時類
package test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo {
public static void main(String[] args) {
Person p = new Person("Lee", 24);
Class c1 = p.getClass();
System.out.println(c1);
Class c2 = Person.class;
System.out.println(c2);
Class c3 = null;
try {
c3 = Class.forName("test.Person");
System.out.println(c3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ClassLoader classLoader = Demo.class.getClassLoader();
try {
Class c4 = classLoader.loadClass("test.Person");
System.out.println(c4);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(c1 == c2); // true
System.out.println(c1 == c3); // true
System.out.println(c1.equals(c2)); // true
System.out.println(c1.equals(c3)); // true
System.out.println("-----------------------------------");
Constructor[] constructors = c1.getConstructors();
for (Constructor con : constructors) {
System.out.println(con);
}
System.out.println("-----------------------------------");
try {
Constructor constructor1 = c1.getConstructor(); // 獲得空參構造方法
Constructor constructor2 = c1.getConstructor(String.class, int.class); // 獲得帶參數的構造方法
Constructor constructor3 = c1.getDeclaredConstructor(int.class, String.class); // 獲得帶參數的構造方法(私有)
System.out.println(constructor1);
System.out.println(constructor2);
System.out.println(constructor3);
Person p1 = (Person) constructor1.newInstance();
Person p2 = (Person) constructor2.newInstance("Jack", 42);
constructor3.setAccessible(true); // 取消運行時的權限檢查
Person p3 = (Person) constructor3.newInstance(17, "Mark");
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("-----------------------------------");
Field[] fileds = c1.getFields();
for (Field f : fileds) {
System.out.println(f);
}
System.out.println("-----------------------------------");
fileds = c1.getDeclaredFields();
for (Field f : fileds) {
System.out.println(f);
}
System.out.println("-----------------------------------");
try {
Field field1 = c1.getField("height"); // 公有
System.out.println(field1);
Field field2 = c1.getDeclaredField("name"); // 私有
System.out.println(field2);
Object obj = c1.newInstance();
field1.set(obj, 185);
// field2.set(obj,"Tim"); // 報錯
System.out.println(obj);
} catch (NoSuchFieldException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
System.out.println("-----------------------------------");
Method[] methods = c1.getMethods();
for (Method m : methods) {
System.out.println(m);
}
System.out.println("-----------------------------------");
try {
Method method1 = c1.getMethod("setAge", int.class);
try {
Object obj = c1.newInstance();
method1.invoke(obj, 15);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
class Person {
private String name;
private int age;
public float height;
public float weight;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
private Person(int age, String name) {
this.age = age;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "test.Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
通過類對象調用newInstance()方法創建對象,默認調用無參數的構造器,初始化新創建的對象,如果這個類沒有默認的構造器,就會拋出一個異常。 所以一般使用Constructor類的newInstance方法去調,可以帶參數,通用一點。
- 反射類型擦除
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class Test{
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("a");
// arrayList.add(1); // invalid
Class c= arrayList.getClass();
Method method = null;
try {
method = c.getMethod("add",Object.class);
method.invoke(arrayList,56);
method.invoke(arrayList,"b");
method.invoke(arrayList,'c');
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
- 反射配置文件
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class Test {
public static void main(String[] args) {
/*
a.properties
#className=Person
#methodName=eat
className=Student
methodName=study
#className=Worker
#methodName=work
*/
try(FileReader fr = new FileReader("d:\\a.properties")){
Properties properties = new Properties();
properties.load(fr);
String className = properties.getProperty("className");
String methodName = properties.getProperty("methodName");
Class c = Class.forName(className);
Object obj = c.newInstance();
Method method = c.getMethod(methodName);
method.invoke(obj);
}catch (IOException e){
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
class Person {
public void eat() {
System.out.println("eat...");
}
}
class Student {
public void study() {
System.out.println("study...");
}
}
class Worker {
public void work() {
System.out.println("work...");
}
}
- 靜態代理
interface PhoneFactory {
void producePhone();
}
class ProxyPhoneFactory implements PhoneFactory{
private PhoneFactory phoneFactory;
ProxyPhoneFactory(PhoneFactory phoneFactory){
this.phoneFactory = phoneFactory;
}
@Override
public void producePhone() {
System.out.println("代理工廠開始生產手機");
phoneFactory.producePhone();
System.out.println("代理工廠完成生產手機");
}
}
class MiPhoneFactory implements PhoneFactory{
@Override
public void producePhone() {
System.out.println("生產小米手機");
}
}
public class StaticProxyTest{
public static void main(String[] args) {
// 被代理類
MiPhoneFactory miPhoneFactory = new MiPhoneFactory();
// 代理類
ProxyPhoneFactory proxyPhoneFactory = new ProxyPhoneFactory(miPhoneFactory);
proxyPhoneFactory.producePhone();
}
}
- 動態代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Human {
String getBelief();
void eat(String food);
}
class SuperMan implements Human {
@Override
public String getBelief() {
return "I can fly!";
}
@Override
public void eat(String food) {
System.out.println("我喜歡吃" + food);
}
}
class MyInvocationHandler implements InvocationHandler {
private Object object; // 需要使用被代理類的對象進行賦值
public void bind(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(object, args);
}
}
class ProxyFactory {
public static Object getProxyInstance(Object obj) {
MyInvocationHandler handler = new MyInvocationHandler();
handler.bind(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
}
}
public class ProxyTest {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
System.out.println(proxyInstance.getBelief());
proxyInstance.eat("小龍蝦");
MiPhoneFactory miPhoneFactory = new MiPhoneFactory();
PhoneFactory phoneFactory = (PhoneFactory) ProxyFactory.getProxyInstance(miPhoneFactory);
phoneFactory.producePhone();
}
}
參考書籍:《瘋狂Java講義》