一、有啥用?
在运行状态,
能让我们知道任意一个类的属性及方法;
能让我们生成任意对象,并调用其方法、改变其属性。
总而言之,反射机制使得我们能够动态获取类信息,动态调用对象方法。
二、怎么用?(反射机制常用到的类及方法)
反射机制将组成类的各个部分分别映射到相应的类对象中,将类信息映射到Class类,将方法信息映射在Method类,将属性信息映射在Field类,将构造方法映射到Constructor类。
Class类:
特点:无共有构造方法,Class对象由jvm加载类文件时自动创建,一个类只会生成一个类对象。
作用:保存运行时类型信息。Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即RTTI。这项信息纪录了每个对象所属的类。从而JVM能使用运行时类型信息选择正确方法去执行,用来保存这些类型信息的类就是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。
获取方法:1、若已有某一个类的实例,则可用实例名.getClass()获取对应的Class对象;2、类名.class获取;3、Class.forName(全路径名);
package testRun; import authorityTest.MemoryCell; public class MemoryCellTest { public static void main(String[] args) throws Exception { MemoryCell a = new MemoryCell(); Class saa = Class.forName("testRun.MemoryCell"); Class saa1 = a.getClass(); Class saa2 = MemoryCell.class; System.out.println(saa.equals(saa1)); System.out.println(saa1.equals(saa2)); Object ooo = saa1.newInstance(); Class<MemoryCell> saa3 = MemoryCell.class; MemoryCell saa3O = saa3.newInstance(); System.out.println(saa3O.equals(a)); } }
运行结果:
true
true
false
可见:三种方式获取的是同一个Class对象,方法1要求已有目标类的实例,用反射的情形较少;方法2需要导入包,依赖太强;方法3是最常用的一种;另,可通过newInstance()方法拿到类的实例,从而调用类中方法,改变对象属性。
Method类:Method类中方法很多,主要介绍获取方法的几个方法,getMethods()、getDeclaredFields,getDeclaredMethod(方法名, 参数类型);前者获取类中公共方法,后者获取所有声明的方法,也可指定方法名获取指定方法。
Field类:与Method类似,getDeclaredFields(),getDeclaredField(属性名);
package testRun; import java.lang.reflect.Field; import java.lang.reflect.Method; import authorityTest.MemoryCell; import overrideTest.Car; public class MemoryCellTest { public static void main(String[] args) throws Exception { Class car = Class.forName("overrideTest.Car"); System.out.println("*****************获取所有public方法*************"); Method[] methodArray = car.getMethods(); for (Method m : methodArray) { System.out.println(m); } System.out.println("*****************获取所有方法*************"); methodArray = car.getDeclaredMethods(); for (Method m : methodArray) { System.out.println(m); } System.out.println("*****************获取私有方法*************"); Method methodPrivate = car.getDeclaredMethod("privateMeth"); System.out.println(methodPrivate); methodPrivate.setAccessible(true); Object obj; obj = car.newInstance(); methodPrivate.invoke(obj, null); System.out.println("*****************获取public成员变量*************"); Field[] params = car.getFields(); for (Field f : params) { System.out.println(f); } System.out.println("*****************获取所有成员变量*************"); params = car.getDeclaredFields(); for (Field f : params) { System.out.println(f); } System.out.println("*****************获取private成员变量*************"); Field param = car.getDeclaredField("SFC"); System.out.println(param); param.setAccessible(true); param.set(obj, 10000); Car caro = (Car) obj; System.out.println(caro.getSFC()); } }
运行结果:
*****************获取所有public方法*************
public static void overrideTest.Car.main(java.lang.String[])
public int overrideTest.Car.getSFC()
public java.lang.String overrideTest.Car.actGenerator(java.lang.String)
public void overrideTest.Car.publicMeth()
public void overrideTest.Car.publicMeth2()
public void overrideTest.Car.privateMeth2()
public void overrideTest.Car.setSFC(int)
public java.lang.String overrideTest.Car.propertyGenerator(java.lang.String)
public int overrideTest.Car.getPowerPerformance()
public void overrideTest.Car.setPowerPerformance(int)
public int overrideTest.Car.getBrakeCharacteristic()
public void overrideTest.Car.setBrakeCharacteristic(int)
public int overrideTest.Car.getHandingStability()
public void overrideTest.Car.setHandingStability(int)
public int overrideTest.Car.getRidingPerformance()
public void overrideTest.Car.setRidingPerformance(int)
public int overrideTest.Car.getTrafficability()
public void overrideTest.Car.setTrafficability(int)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
*****************获取所有方法*************
public static void overrideTest.Car.main(java.lang.String[])
private void overrideTest.Car.privateMeth()
public int overrideTest.Car.getSFC()
public java.lang.String overrideTest.Car.actGenerator(java.lang.String)
public void overrideTest.Car.publicMeth()
public void overrideTest.Car.publicMeth2()
public void overrideTest.Car.privateMeth2()
public void overrideTest.Car.setSFC(int)
public java.lang.String overrideTest.Car.propertyGenerator(java.lang.String)
public int overrideTest.Car.getPowerPerformance()
public void overrideTest.Car.setPowerPerformance(int)
public int overrideTest.Car.getBrakeCharacteristic()
public void overrideTest.Car.setBrakeCharacteristic(int)
public int overrideTest.Car.getHandingStability()
public void overrideTest.Car.setHandingStability(int)
public int overrideTest.Car.getRidingPerformance()
public void overrideTest.Car.setRidingPerformance(int)
public int overrideTest.Car.getTrafficability()
public void overrideTest.Car.setTrafficability(int)
*****************获取私有方法*************
private void overrideTest.Car.privateMeth()
i'm a private Method!
*****************获取public成员变量*************
public int overrideTest.Car.handingStability
public int overrideTest.Car.ridingPerformance
*****************获取所有成员变量*************
private int overrideTest.Car.powerPerformance
private int overrideTest.Car.SFC
private int overrideTest.Car.brakeCharacteristic
public int overrideTest.Car.handingStability
public int overrideTest.Car.ridingPerformance
int overrideTest.Car.trafficability
*****************获取private成员变量*************
private int overrideTest.Car.SFC
10000
可见利用反射可获取类中全权限的属性及方法。