反射第一步
获取Class类对象,这样才能获取类中的所有属性、行为...;
获取Class类的三种方式
方式一:Class c1 = 类名.class;
方式二:Class c2 = 对象名.getClass;
方式三:Class c3 = Class.forName("全限定包名");
代码举例:
import org.junit.Test;
/**
* 反射第一步:
* 获取Class类对象,这样才能够解析类的全部成分。
*
* JVM同一种类型的字节码文件只有一份
* 获取Class类字节码对象的三种方式:
* 1.Class c2 = 类名.class;
* 2.Class c3 = 对象名.getClass;
* 3.Class c1 = Class.forName("全限定类名(包名+类名)");(最常用)
*/
public class ClassTest {
@Test
public void test1() throws Exception {
System.out.println("=====类=====");
// 1.Class c2 = 类名.class;获取字节码对象
Class cls = ClassTest.class;
// 2.Class c3 = 对象名.getClass;获取字节码对象
Class<? extends ClassTest> cls1 = new ClassTest().getClass();
// 判断获取的字节码对象是不是同一个对象
System.out.println("类1:"+(cls == cls1));
// 3.Class c1 = Class.forName("全限定类名(包名+类名)");
// 通过完全限定名进行获取 选择.java下的C图标右键点击 Copy Qualified Name获取全限定类名
Class<?> forName = Class.forName("cn.meituan.reflect.ClassTest");
// 判断获取的字节码对象是不是同一个对象
System.out.println("类2:"+(cls == forName));
}
}
使用反射获取构造器对象并使用
反射的第一步是先得到类对象,然后从类对象中获取类的成分对象。
Class类中用于获取构造器的方法
方法 说明
Constructor<?>[] getconstructors() 返回所有构造器对象的数组(只能拿public的)
Constructor<?>[] getDeclaredConstructors() (常用) 返回所有构造器对象的数组,存在就能拿到
constructor<T> getconstructor(Class<?>... parameterTypes) 返回单个构造器对象(只能拿public的)
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)(常用) 返回单个构造器对象,存在就能拿到
获取构造器的作用任然是去初始化一个对象并返回。
Constructor中用于创建对象的方法
- T newInstance(Object... initargs)
- initargs 创建对象向构造方法中的传入的给对象那个初始化值的数据
import java.lang.reflect.Constructor;
import org.junit.Test;
/**
* 使用反射技术获取构造器对象并使用
*
反射的第一步是先得到类对象,然后从类对象中获取类的成分对象。
Class类中用于获取构造器的方法
方法 说明
Constructor<?>[] getconstructors() 返回所有构造器对象的数组(只能拿public的)
Constructor<?>[] getDeclaredConstructors() (常用) 返回所有构造器对象的数组,存在就能拿到
constructor<T> getconstructor(Class<?>... parameterTypes) 返回单个构造器对象(只能拿public的)
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)(常用) 返回单个构造器对象,存在就能拿到
*
*/
public class ConstructorTest {
// 注解@Test用来进行单元测试
@Test
public void test1() throws Exception, Exception{
// 反射第一步获取类对象 字节码对象cls
Class<User> cls = User.class;
System.out.println("===============1=================");
// 通过类对象cls调用构造器方法
// 1.Constructor<?>[] getconstructors()
// 返回所有构造器对象的数组(只能拿public的)
Constructor<?>[] c1 = cls.getConstructors();
//遍历获取所有public修饰的构造器对象
for (Constructor<?> co : c1) {
System.out.println("getConstructors所有公共的构造器对象"+co);// public cn.meituan.reflect.User()
//System.out.println(co.getName());//获取全限定名 cn.meituan.reflect.User
}
System.out.println("===============2=================");
// 2.Constructor<?>[] getDeclaredConstructors()
// 返回所有构造器对象的数组,存在就能拿到(包括所有的public private Object..等等)
Constructor<?>[] dc = cls.getDeclaredConstructors();
// 遍历所有构造器对象(public private..)
for (Constructor<?> co1 : dc) {
System.out.println("getDeclaredConstructors所有构造器对象"+co1);
}
System.out.println("===============3===============");
// 3.constructor<T> getconstructor(Class<?>... parameterTypes)
// 返回单个构造器对象(只能拿public的)
Constructor<User> noargs = cls.getConstructor();// 没有参数,获取的是无参构造方法
System.out.println("getConstructor获取共有无参构造器对象"+noargs);
// public Constructor<T> getConstructor(Class<?>... parameterTypes)
// 参数是带参构造方法的类对象
//通过类对象获取 public User(String name, Integer age, String sex, String address) User类中有参构造方法
Constructor<User> co2 = cls.getConstructor(String.class,Integer.class,String.class,String.class);
System.out.println("getConstructor获取共有带参构造器对象"+co2);
System.out.println("===============4===============");
// 4.Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
// 返回单个构造器对象,存在就能拿到
//通过类对象获取私有构造器对象private User( Integer age, String sex, String address)// 主要是通过后面参数列表确定是那个构造器
Constructor<User> co3 = cls.getDeclaredConstructor(Integer.class,String.class,String.class);
// 如果需要获取私有构造器对象,需要用私有构造器对象解锁,而不是类对象解锁,暴力反射(打开java权限设置)
co3.setAccessible(true);
System.out.println("getDeclaredConstructor获取私有带参构造器对象,需要暴力反射"+co3);
// 获取带参构造器对象public User(String name, Integer age, String sex, String address)
Constructor<User> co4 = cls.getDeclaredConstructor(String.class, Integer.class, String.class, String.class);
System.out.println("getDeclaredConstructor获取共有带参构造器对象"+co3);
//T newInstance(Object... initargs)
//initargs 创建对象向构造方法中的传入的给对象那个初始化值的数据
// 获取到构造器对象可以用来干什么?
// 1.创建对象
// 反射得到的构造器用来自己创建对象
// noargs 无参构造方法对象创建对象
User newInstance = noargs.newInstance();
System.out.println("获取构造器对象"+newInstance);
// 2.如果是非public的构造器,需要打开权限(暴力反射),再创建对象
// co3是 私有带参构造方法
User newInstance2 = co3.newInstance(18,"张三","张三大"); // 创建对象参数列表是对构造器对象进行赋值
System.out.println("newInstance 创建public构造器对象1"+newInstance2);
}
}
使用反射获取成员变量对象并使用
获取成员变量的作用是对其进行赋值取值。
常用方法:
Field[ getFields()
返回所有成员变量对象的数组(只能拿public的)
Field getDeclaredFields()
返回所有成员变量对象的数组,存在就能拿到
Field getField(String name)
返回单个成员变量对象(只能拿public的)
Field getDeclaredField(String name)
返回单个成员变量对象,存在就能拿到
Field的方法:给成员变量赋值和取值
void set(object obj, 0bject value):给对象注入某个成员变量数据
object get(object obj):获取对象的成员变量的值。
void setAccessible(true) ;暴力反射,设置为可以直接访问私有类型的属性。
import java.lang.reflect.Field;
import org.junit.Test;
/**
* 字段/属性(成员变量)(Field)
使用反射技术获取成员变量对象并使用
●反射的第一步是先得到类对象,然后从类对象中获取类的成分对象。 Class类中用于获取成员变量的方法
方法
说明
Field[ getFields()
返回所有成员变量对象的数组(只能拿public的)
Field getDeclaredFields()
返回所有成员变量对象的数组,存在就能拿到
Field getField(String name)
返回单个成员变量对象(只能拿public的)
Field getDeclaredField(String name)
返回单个成员变量对象,存在就能拿到
*/
public class FieldTest {
// 创建一个测试方法进行测试
@Test
public void test() throws Exception, Exception {
// 创建类对象
Class<User> user = User.class;
System.out.println("==========1=========");
// 1.Field[ getFields()
// 返回所有成员变量对象的数组(只能拿public的)
Field[] fields = user.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("========2===========");
// 2.Field getDeclaredFields()
// 返回所有成员变量对象的数组,存在就能拿到
Field[] declaredFields = user.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field);
}
// 3.Field getField(String name)
// (只能拿单个public的)
System.out.println("==========3=========");
Field field = user.getField("name1");
System.out.println(field.getName());
// 4.Field getDeclaredField(String name)
// 返回单个成员变量对象,存在就能拿到
System.out.println("==========4========");
//获取到某个的私有成员变量
Field ageF = user.getDeclaredField("age");
System.out.println(ageF);
/**
Field的方法:给成员变量赋值和取值
void set(object obj, 0bject value):给对象注入某个成员变量数据
object get(object obj):获取对象的成员变量的值。
void setAccessible(true) ;暴力反射,设置为可以直接访问私有类型的属性。
*/
//暴力反射打开 (java权限设置) 对age成员变量进行赋值
ageF.setAccessible(true);
// 创建一个User对象对成员变量进行赋值
// 通过类对象去调用newInstance获取一个对象
User newInstance = user.newInstance();
// void set(object obj, 0bject value):给对象注入某个成员变量数据
// obj表示的是那个对象 value表示的是对ageF的对应的成员变量
ageF.set(newInstance, 18);
System.out.println(newInstance); // 打印user2看是否赋值成功
// User [name=null, age=18, sex=null, address=null]
// 获取私有成员变量 sex
Field sexF = user.getDeclaredField("sex");
// 对获取到的私有成员变量进行暴力反射打开权限(先获取到成员变量再暴力反射打开)
sexF.setAccessible(true);
// 参数user2表示是那一个对象 男是对sex成员变量进行赋值
sexF.set(newInstance, "男");
Object object = sexF.get(newInstance);// 利用get方法获取sexF对应的成员变量值
System.out.println("获取sex成员变量的值:"+object);
System.out.println(newInstance);
// User [name=null, age=18, sex=男, address=null]
}
}
利用反射获取成员方法对象并使用
获取成员方法的作用依然是在某个对象中执行这个方法
反射的第一步是先得到类对象,然后从类对象中获取类的成分对象。Class类中用于获取成员方法的方法
方法
说明
Method[] getMethods()
返回所有成员方法对象的数组(只能拿public的)
Method[ ] getDeclaredMethods()
返回所有成员方法对象的数组,存在就能拿到
Method getMethod( string name,class<?>... parameterTypes)
返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name,Class<?>... parameterTypes)
返回单个成员方法对象,存在就能拿到 name是方法名 parameterTypes是方法中参数类型.class
Method类中用于触发执行的方法
运行方法
Object invoke(object obj, object. . . args)
参数一:用obj对象调用该方法 obj表示的是类的对象 ,方法的参数
参数二:args是调用方法的传递的参数(方法中如果没有就不写)返回值:方法的返回值(如果没有就不写)
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Test;
/**
* 使用反射技术获取方法对象并使用
反射的第一步是先得到类对象,然后从类对象中获取类的成分对象。Class类中用于获取成员方法的方法
方法
说明
Method[] getMethods()
返回所有成员方法对象的数组(只能拿public的)
Method[ ] getDeclaredMethods()
返回所有成员方法对象的数组,存在就能拿到
Method getMethod( string name,class<?>... parameterTypes)
返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name,Class<?>... parameterTypes)
返回单个成员方法对象,存在就能拿到 name是方法名 parameterTypes是方法中参数类型.class
Method类中用于触发执行的方法
运行方法
Object invoke(object obj, object. . . args)
参数一:用obj对象调用该方法 obj表示的是类的对象 ,方法的参数
参数二:调用方法的传递的参数(如果没有就不写)返回值:方法的返回值(如果没有就不写)
*/
public class NormalMethodTest {
@Test
public void test() throws Exception, Exception{
// 反射的第一步是先得到类对象,然后从类对象中获取类的成分对象。Class类中用于获取成员方法的方法
Class<User> cls = User.class;
System.out.println("======1======");
// 1.Method[] getMethods()
// 返回所有成员方法对象的数组(只能拿public的)(包括equals和hashcode这些...)
Method[] m1 = cls.getMethods();
//对所有public修饰的成员变量进行遍历
for (Method method : m1) {
System.out.println(method.getName());
}
System.out.println("=====2======");
// 2.Method[ ] getDeclaredMethods()
// 返回所有成员方法对象的数组,存在就能拿到
Method[] m2 = cls.getDeclaredMethods();
for (Method method : m2) {
System.out.println(method.getName()+","+method.getParameterCount());
}
System.out.println("======3======");
// 3.Method getMethod( string name,class<?>... parameterTypes)
// 返回单个成员方法对象(只能拿public的)
Method method = cls.getMethod("getNum");
Method method2 = cls.getMethod("setAge", Integer.class);
System.out.println(method);
System.out.println(method2);
System.out.println("======4======");
// 4.Method getDeclaredMethod(String name,Class<?>... parameterTypes)
// 返回单个成员方法对象,存在就能拿到
// name表示方法名 parameterTypes表示参数字节码文件
Method setS = cls.getDeclaredMethod("setSex", String.class);
//
System.out.println(setS);
//创建一个User对象
//User user = new User();
User newInstance = cls.newInstance();
// invoke方法 obj是 是创建的对象(user),args是对参数进行赋值
setS.invoke(newInstance, "女");//setS表示的是sex
System.out.println(newInstance);
// newinstance是哪一个对象,后面参数是对age进行赋值
method2.invoke(newInstance, 118);//method2表示的是age
System.out.println(newInstance);
}
}