java基础之反射的使用

反射

通过.class来得到对象,属性,方法的一种手段

1. 类对象和他的三种获取方式

  • 通过对象
    • Class cls = obj.getClass();
  • 通过类名(常用)
    • Class cls = Test.class;
  • 通过Class的静态方法
    • Class cls = Class.forName(“类全名”);

/**
 * 字节码对象的三种获取方式
 * 1: 通过对象.getClass()方法; 直接能够得到这个类的对象,就可以直接通过对象获取 Class cls1 = p.getClass();
 * 2: 通过类名.class 来获取这个字节码对象 ; 和Person类在一起,就可以使用这个
 * 3: 通过静态方法来获取这个对象; 只知道这个类的类全名; 可以使用这个手段;
 */
public class DemoGetClass {

	public static void main(String[] args) {

		//正常获取Person对象
		Person person = new Person();
		
		//反射获取Person对象,Class cls; 这个就代表一个.class文件
		
		//1: 通过对象.getClass()方法
		Class class1 = person.getClass();
		
		//2: 通过类名.class 来获取这个字节码对象
		Class class2 = Person.class;
		
		//3: 通过静态方法来获取这个对象
		try {
			Class class3 = Class.forName("com.qianfeng.xqc.day0319.fanshe.Person");
			System.out.println(class3 == class2);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		System.out.println(class1);
		System.out.println(class2);
		
	}
}

2. 通过反射获取构造器

	/**
	 * 通过反射获取我们.class对象的所有构造器
	 * 作用: 能够实例一个对象
	 */
	public static void test1() {
		
		Class cls = Person.class;// 获取了person的字节码对象
		
		try {
			//获取构造器对象
			Constructor constructor = cls.getConstructor();
			
			// 获取public的构造器
			Constructor[] constructors = cls.getConstructors();
			for(Constructor c : constructors) {
				c.getParameterTypes();//获取参数类型Class
				System.out.println(c.getName());
			}
			
			System.out.println("===============================");
			
			// 获取所有的构造器
			Constructor[] declaredConstructors = cls.getDeclaredConstructors();
			for(Constructor c : declaredConstructors) {
				System.out.println(c.getName());
			}
			
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		
	}

}

3. 通过反射获取对象实例

	/**
	 * 获取不同的构造器,来实例化对象
	 */
	public static void test2() {
		
		Class cls = Person.class;
		
		try {
			//获取公共的构造器,没有参数
			Person p1 = (Person) cls.newInstance();//获取默认的无参的构造器,创建对象
			
			//无参的构造器
			Constructor constructor = cls.getConstructor();
			Person p2 = (Person) cls.newInstance();
			
			//获取带参数的构造器,使用带参的构造器实例,指定参数,实例化一个对象
			Constructor constructor3 = cls.getDeclaredConstructor(char.class);//public
			Person p3 = (Person) constructor3.newInstance('a');
			Constructor constructor4 = cls.getDeclaredConstructor(int.class);//default
			Person p4 = (Person) constructor4.newInstance(5);
			
			//传值的时候,一定要和你获取构造器的时候的数据类型匹配
			Constructor constructor5 = cls.getDeclaredConstructor(int.class,String.class);
			Person p5 = (Person) constructor5.newInstance(5,"sda");
			
            
			//获取私有的构造器,并且能够实例化对象
			Constructor constructor6 = cls.getDeclaredConstructor(String.class);
			
			//如果通过反射去破解我们私有属性、构造器、方法,必须破解他的权限;
			constructor6.setAccessible(true);			
			Person p6 = (Person) constructor6.newInstance("ss");			
			
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
	}

4. 通过反射获取属性,并且修改对象的属性值

​ 案例:修改一个类的私有属性的值;


import java.lang.reflect.Field;
/**
 * 通过反射,来获取我们的所有的属性
 *
 */
public class DemoGetShuxing {

	public static void main(String[] args) {

		modifysx();
		
	}
	
	/**
	 * 修改对象的私有属性值
	 */
	public static void modifysx() {
		
		//得到这个属性
		Class cls = Person.class;
		
		try {
			//获取私有属性age对象
			Field declaredField = cls.getDeclaredField("age");
			
			//需要通过setAccessible()方法破解私有属性的开关,设置为true,就代表可以访问这个私有属性
			declaredField.setAccessible(true);
			
			//通过对象,才能访问这个对象的 某个属性或者修改 某个属性的值
			Person p = (Person) cls.newInstance();
			
			//使用属性去得到属性的值; 得到p1对象的这个属性的值
			int age = declaredField.getInt(p);//得到p对象的 age属性的值;
			System.out.println("age:" + age);
			
			//对这个属性的值,进行修改
			declaredField.setInt(p, 100);//修改p对象age属性的值,修改成100
			Object object = declaredField.get(p);
			System.out.println("修改后age:" + object);
			
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		
	}

	/**
	 * 通过反射获取属性
	 */
	public static void getsx() {
		Class cls = Person.class;

		// 根据属性名称,来获取这个属性对象
		try {
			Field field = cls.getField("id");// 只能得到public修饰的属性
			Field field2 = cls.getDeclaredField("age");// 获取名字为id的属性;(所有的属性都能获取)

			System.out.println(field.getName());
			System.out.println(field2.getName());
			System.out.println("---------------------");

			// 获取public修饰过的属性
			Field[] fields = cls.getFields();
			for (Field f : fields) {
				System.out.println(f.getName());
			}

			System.out.println("---------------------");

			// 获取所有属性
			Field[] declaredFields = cls.getDeclaredFields();
			for (Field f : declaredFields) {
				System.out.println(f.getName());
			}

		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}

}

5. 通过反射获取方法,并且调用对象的方法

案例:调用一个类的私有方法
	/**
	 * 调用一个类的私有方法
	 */
	public static void getprivatemethod() {
		
		Class cls = Person.class;
		try {
			Method declaredMethod = cls.getDeclaredMethod("test4");
			
			//获取一个对象
			Object obj = cls.newInstance();
			
			//私有方法使用需要破解权限
			declaredMethod.setAccessible(true);
			
			//调用方法
			declaredMethod.invoke(obj);
			
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取一个类的方法
	 */
	public static void getmethod() {
		
		Class cls = Person.class;
		
		try {
			//获取public的方法(根据方法名称)
			Method method = cls.getMethod("test1");
			//获取所有public的方法
			Method[] methods = cls.getMethods();
			for(Method m : methods) {
				System.out.println(m.getName());
			}
			
			System.out.println("--------------");
			
			//获取所有的修饰符修饰的方法(根据方法名称)
			Method declaredMethod = cls.getDeclaredMethod("test4");
			//获取本类所有的方法
			Method[] declaredMethods = cls.getDeclaredMethods();
			for(Method m : declaredMethods) {
				System.out.println(m.getName());
			}
			
			
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		
	}

}

带参数的方法调用
	/**
	 * 调用一个类的带参数返回值的私有方法
	 */
	public static void getprivatemethodcs() {
		
		Class cls = Person.class;
		try {
			//获取这个方法
			Method declaredMethod = cls.getDeclaredMethod("plus",int.class,int.class);
			
			//获取一个对象
			Object obj = cls.newInstance();
			
			//私有方法使用需要破解权限
			declaredMethod.setAccessible(true);
			
			//调用这个方法; 需要传递2个参数;参数的类型是 int 和 int
			//如果方法有返回值,一定要使用一个参数去接收这个返回值;			
			//调用方法
			Object result = declaredMethod.invoke(obj,10,12);
			System.out.println(result);
			
			
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值