反射第一步

获取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中用于创建对象的方法

  1. T newInstance(Object... initargs)
  2. 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);	
		
	}
}