Java 反射入门总结

1.概念

  • 反射机制是在运行状态中:
    对于任意一个类,都能够知道这个类的所有属性和方法。
    对于任意一个对象,都能够调用它的任意一个方法和属性。

2.提供的功能

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的的成员变量和方法
  • 在运行时调用任意一个对象的方法
  • 生成动态代理

3.获得反射入口的三种方式(获得类)

1).Class.forName(全类名)(推荐使用)

try {
		Class<?> classStu = Class.forName("reflect.Student");
		System.out.println(classStu);
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}

2).类名.class

	Class<?> classStu2 = Student.class;
	System.out.println(classStu2);

3).对象.getClass()

	Student stu = new Student();
	Class<?> classStu3 = stu.getClass();
	System.out.println(classStu3);

4.通过反射获取类的相关信息

1).获取所有的公共的方法

  • 方法范围是本类以及父类、接口中的所有公有的方法
  • 符合访问修饰的规律
Method[] methods = classStu.getMethods();
    		for(Method method : methods) {
    			System.out.println(method);
    		}

2).获取该类的所有接口

Class<?>[] interfaces = classStu.getInterfaces();
		for(Class<?> inter : interfaces) {
			System.out.println(inter);
		}

3).获取该类的父类

Class<?> superClass = classStu.getSuperclass();
		System.out.println(superClass);

4).获取该类的所有的构造方法

Constructor<?>[] constructors = classStu.getConstructors();
		for (Constructor constructor : constructors) {
			System.out.println(constructor);
		}

5).获取所有公共属性

  • 属性范围是本类以及父类中的所有公有的属性
Field[] fields = classStu.getFields();
		for (Field field : fields) {
			System.out.println(field);
		}

6).获取当前类的所有方法

  • 包含私有方法(忽略访问修饰符)
  • 不包括父类方法,但包含接口的实现方法
Method[] declaredMethods = classStu.getDeclaredMethods();
		for (Method declaredMethod : declaredMethods) {
			System.out.println(declaredMethod);
		}

7).获取当前类的所有属性

  • 包含私有属性
  • 不包含父类属性
Field[] declaredFields = classStu.getDeclaredFields();
		for (Field declaredField : declaredFields) {
			System.out.println(declaredField);
		}

8).获取当前反射所代表类(接口)的对象(实例)

  • 相当于new了一个对象
Object newInstance = classStu.newInstance();
		Student stu = (Student)newInstance;
		stu.breathe();

5.通过反射获取对象的实例,并操作对象(实例)

1).操作属性

  • 使用场景:没有set构造器
Student stu = (Student)classStu.newInstance();
		Field idFieAge = classStu.getDeclaredField("age");
		idFieAge.setAccessible(true);//修改访问权限(private)
		idFieAge.set(stu, 1);//相当于stu.setAge(1);
		System.out.println(stu.getAge());

2).操作函数

  • 无参私有函数
Student stu = (Student)classStu.newInstance();
		Method method = classStu.getDeclaredMethod("sleep", null);//(函数名,参数)
		method.setAccessible(true);//private函数
		method.invoke(stu, null);//null表示无参数
  • 有参公有函数
Student stu = (Student)classStu.newInstance();
		Method method = classStu.getDeclaredMethod("habby", String.class);//参数类型
		method.invoke(stu, "篮球");

注:在反射中,基本类型(int)和基本类型的包装类(Integer)是不同的类型

3).操作构造函数

  • 可以直接new出一个对象
Constructor<?> constructor = classStu.getConstructor(null);
		Student stu = (Student)constructor.newInstance();
		System.out.println(stu);

6.动态加载类名和方法

  • class.txt
classname=reflect.Student
methodname=staticMethod
  • 动态调用
Properties prop = new Properties();
		prop.load(new FileReader("class.txt"));
		
		String classname = prop.getProperty("classname");
		String methodname = prop.getProperty("methodname");
		
		Class<?> classStu = null;
		//反射入口
		try {
			classStu = Class.forName(classname);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		Method method = classStu.getMethod(methodname);
		method.setAccessible(true);
		method.invoke(classStu.newInstance());

7.通过反射越过泛型检查

  • 在Integer列表中加入String
ArrayList<Integer> list = new ArrayList();
		list.add(123);
		list.add(22);
		
		 Class<?> classStu = list.getClass();
		
		Method method = classStu.getMethod("add", Object.class);
		method.invoke(list, "ssss");
		System.out.println(list);

上述代码输出结果
注:虽然可以通过反射访问private等访问修饰符不允许访问的属性和方法,也可以忽略掉泛型检查,但不推荐使用,可能会引起程序的混乱

8.通过反射实现万能set方法

  • obj:对象
  • propertyName:属性名
  • value:属性值
public static void setProperty(Object obj, String propertyName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		
		Class<?> clazz = obj.getClass();
		Field field = clazz.getDeclaredField(propertyName);
		field.setAccessible(true);
		field.set(obj, value);
		
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值