java的反射机制是在运行状态中的,对于任意一个类都能够知道这个类的所有的方法和属性。例如 通过Student的具体对象张三---》找到它属于的类Student.class。我们得到Student类之后我们就可以得到类里面所有的方法和属性;所以第一步我们先要获得Class对象:可以理解为类的描述类,就是到底是哪一个类 :Student、Teacher。。。
获得描述类的方法有三种:
1、通过具体的对象获得,例如通过张三获得:每一个对象的顶级父对象Object含有一个getClass()方法,返回该对象所属的类
String string = new String();
Class aClass = string.getClass();
System.out.println(aClass);
2、通过具体的类名 具体的类名即是一个Class对象,Class有一个异常的static class属性,通过该属性可以获得具体的类名
Class class1 = Long.class;
System.out.println(class1);
3、通过Class的静态方法forName(“具体的全限定类名”),返回具体的类名
Class> aClass1 = Class.forName("java.lang.Long");
System.out.println(aClass1);
获取构造方法,步骤如下:
1. 获取到Class对象,即获得描述类对象clazz
2. 获取构造方法
通过clazz对象的getConstructors()或者getConstructor(“具体的构造参数的描述类对象,例如:String.class”)获得public权限的
如果想获得私有的需要加上Declared,例如:getDeclaredConstructor();然后使用构造方法的setAccessible(true);//取消 Java 语言访问检查
3. 通过构造方法类Constructor中的方法,创建对象,例如具体的学上张三
a)通过构造方法的newInstance('具体获得构造方法时传入的类型'),无参构造可以不填写
b)快捷方式,通过默认的public 权限的无参获得 直接描述类对象clazz.newInstance();
import java.lang.reflect.Constructor;
/**
* ProjectName: Test
* ClassName: ReflectDemo02
* Description: 从class对象中获得所需要的成员
* Company:www.ecostor.biz
*Constructor类:描述构造方法对象的类
* @version 1.0
* @author jiewenbo
* @date 2019/5/11 11:03
*/
public class ReflectDemo02 {
public static void main(String[] args) throws Exception{
//获得类对象
Class> unitInfo = Class.forName("UnitInfo");
//通过class文件对象过的构造方法,获得class文件对象中所有的公共的构造方法
// Constructor>[] constructors = unitInfo.getConstructors();
// for(Constructor temp: constructors){
// System.out.println(temp);
// }
Constructor> constructor = unitInfo.getConstructor();
System.out.println(constructor);
//运行构造器 通过Constructor类的newInstance.获得对象
Object o = constructor.newInstance();
}
}
import java.lang.reflect.Constructor;
/**
* ProjectName: Test
* ClassName: ReflectDemo03
* Description: 通过反射获得有参的构造方法并运行
* Company:www.ecostor.biz
*
* @version 1.0
* @author jiewenbo
* @date 2019/5/11 11:24
*/
public class ReflectDemo03 {
public static void main(String[] args) throws Exception{
//获得类对象
Class> unitInfo = Class.forName("UnitInfo");
Constructor> constructor = unitInfo.getConstructor(String.class);
System.out.println(constructor);
//运行构造器 通过Constructor类的newInstance.获得对象
UnitInfo o = (UnitInfo)constructor.newInstance("nihao");
System.out.println(o.getUnitCode());
}
}
/**
* ProjectName: Test
* ClassName: ReflectDemo04
* Description: 反射获得构造方法,并运行(快捷方式):前提时该对象必须有无参的构造方法,构造方法的权限必须是public
* Company:www.ecostor.biz
*
* @version 1.0
* @author jiewenbo
* @date 2019/5/11 11:32
*/
public class ReflectDemo04 {
public static void main(String[] args) throws Exception{
Class> unitInfo = Class.forName("UnitInfo");
//Class类方法中定义了一个方法T newInstance();直接创建别反射对象
Object o = unitInfo.newInstance();
}
}
反射成员变量
在反射机制中,把类中的成员变量使用类Field表示。可通过Class类中提供的方法获取成员变量:
2.public Field[] getDeclaredFields() 获取所有的 变量 (包含私有)
public class FieldDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
//获取Class对象
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//获取成员变量
//多个变量
//Field[] fields = c.getFields();
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("-----------------");
//一个变量
//public int age;
Field ageField = c.getField("age");
System.out.println(ageField);
//private String address
Field addressField = c.getDeclaredField("address");
System.out.println(addressField);
}
}
使用成员变量
获取成员变量,步骤如下:
1. 获取Class对象
2. 获取构造方法
3. 通过构造方法,创建对象
4. 获取指定的成员变量(私有成员变量,通过setAccessible(boolean flag)方法暴力访问)
5. 通过方法,给指定对象的指定成员变量赋值或者获取值
在指定对象obj中,将此 Field 对象表示的成员变量设置为指定的新值
返回指定对象obj中,此 Field 对象表示的成员变量的值
import java.lang.reflect.Field;
/**
* ProjectName: Test
* ClassName: ReflectDemo06
* Description: 反射成员变量并修改值
* Company:www.ecostor.biz
*
* @author jiewenbo
* @version 1.0
* @date 2019/5/11 15:18
*/
public class ReflectDemo06 {
public static void main(String[] args) throws Exception {
Class unitInfo = Class.forName("UnitInfo");
Object o = unitInfo.newInstance();
//通过getFields(),获得所有的公共的成员变量 返回值Field[] Field类获得成员变量的对象
Field[] fields = unitInfo.getDeclaredFields();
for (Field temp : fields) {
System.out.println(temp);
}
//获得指定的成员变量 Class类的方法 getField(成员变量的名字)
Field unitCode = unitInfo.getDeclaredField("unitCode");
//修改变量的值 使用的是Field 的 void set("Object的对象","值") Object对象指的是当前反射的Class的对象
unitCode.setAccessible(true);
System.out.println(unitCode);
unitCode.set(o, "aaaaaaa");
System.out.println(unitCode.get(o));
}
}
反射成员方法
在反射机制中,把类中的成员方法使用类Method表示。可通过Class类中提供的方法获取成员方法:
public Method getMethod(String name, Class>... parameterTypes)
获取public 修饰的方法
public Method getDeclaredMethod(String name, Class>... parameterTypes)
获取任意的方法,包含私有的
参数1: name 要查找的方法名称; 参数2: parameterTypes 该方法的参数类型
2.返回获取多个方法:
1. public Method[] getMethods() 获取本类与父类中所有public 修饰的方法
2. public Method[] getDeclaredMethods() 获取本类中所有的方法(包含私有的)
public class MethodDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
//获取Class对象
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//获取多个方法
//Method[] methods = c.getMethods();
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("-----------------------");
//获取一个方法:
//public void method1()
Method method = c.getMethod("method1", null);
System.out.println(method);
//public String method4(String name){
method = c.getMethod("method4", String.class);
System.out.println(method);
//私有方法
//private void method5()
method = c.getDeclaredMethod("method5", null);
System.out.println(method);
}
}
通过反射,创建对象,调用指定的方法
获取成员方法,步骤如下:
1. 获取Class对象
2. 获取构造方法
3. 通过构造方法,创建对象
4. 获取指定的方法
5. 执行找到的方法
public Object invoke(Object obj, Object... args)
执行指定对象obj中,当前Method对象所代表的方法,方法要传入的参数通过args指定。
import java.lang.reflect.Method;
import java.util.Map;
/**
* ProjectName: Test
* ClassName: ReflectDemo07
* Description: 反射获取成员方法并运行
* Company:www.ecostor.biz
*
* @author jiewenbo
* @version 1.0
* @date 2019/5/11 15:35
*/
public class ReflectDemo07 {
public static void main(String[] args) throws Exception {
Class> unitInfo = Class.forName("UnitInfo");
Object o = unitInfo.newInstance();
//使用Class 的getMethods()获得成员变量的所有的公共的成员方法,包括继承的
Method[] methods = unitInfo.getMethods();
for (Method temp : methods) {
System.out.println(temp);
}
//获取指定的方法 getMethod()
Method getId = unitInfo.getMethod("getId");
System.out.println(getId);
//通过Method 类中的invoke来调用
Object invoke = getId.invoke(o);
System.out.println(invoke);
}
}