Java反射代码

Reflection是视为动态语言的关键,反射机制运行程序在执行期间借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及其方法。

最近看了下Java的高级用法,其中反射机制用的很多,身为一只小白的我一脸懵逼,what?反射是什么鬼?

反射机制能干什么?

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

以下是基本展示了反射机制的使用(获取Class类、构造参数、获取调用->方法、属性)

JavaBean: 

package jiang;

public class User {
	  private String name = "None";
	  private int age;
	  public User() {
		  
	  }
	  public User(String name, int age) {
	    super();
	    this.name = name;
	    this.age = age;
	  }
	  private String getName() {
	    return name;
	  }
	  private void setName(String name) {
	    this.name = name;
	  }
	  public int getAge() {
	    return age;
	  }
	  public void setAge(int age) {
	    this.age = age;
	  }
	  @Override
	  public String toString() {
	    return "User [name=" + name + ", age=" + age + "]";
	  }
	}

 Java反射:

package jiang;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestMain {
	public static void main(String[] args)
			throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException,
			InvocationTargetException, NoSuchFieldException, SecurityException, NoSuchMethodException {

		// 获取Class对象的三种方式
		System.out.println("根据类名:  \t" + User.class);
		System.out.println("根据对象:  \t" + new User().getClass());
		System.out.println("根据全限定类名:\t" + Class.forName("jiang.User"));

		System.out.println("\n");

		// 常用的方法
		Class userClass = Class.forName("jiang.User");
		System.out.println("获取全限定类名:\t" + userClass.getName());
		System.out.println("获取类名:\t" + userClass.getSimpleName());
		System.out.println("实例化:\t" + userClass.newInstance());

		System.out.println("\n");

		// 获取全部的构造函数
		Constructor<?>[] constructors = userClass.getConstructors();
		// 取消安全性检查,设置后才可以使用private修饰的构造函数,也可以单独对某个构造函数进行设置
		// Constructor.setAccessible(constructors, true);
		for (int i = 0; i < constructors.length; i++) {
			Class<?> parameterTypesClass[] = constructors[i].getParameterTypes();
			System.out.print("第" + i + "个构造函数:\t (");
			for (int j = 0; j < parameterTypesClass.length; j++) {
				System.out.print(parameterTypesClass[j].getName() + (j == parameterTypesClass.length - 1 ? "" : "\t"));
			}
			System.out.println(")");
		}
		// 调用构造函数,实例化对象
		System.out.println("实例化,调用无参构造:\t" + constructors[0].newInstance());
		System.out.println("实例化,调用有参构造:\t" + constructors[1].newInstance("Anglag", 35));

		User user = (User) userClass.newInstance();
		// 获取当前类所有属性
		Field fields[] = userClass.getDeclaredFields();
		// 获取公有属性(包括父类)
		// Field fields[] = cl.getFields();
		// 取消安全性检查,设置后才可以获取或者修改private修饰的属性,也可以单独对某个属性进行设置
		Field.setAccessible(fields, true);
		for (Field field : fields) {
			// 获取属性名 属性值 属性类型
			System.out.println("属性名:" + field.getName() + "\t属性值:" + field.get(user) + "  \t属性类型:" + field.getType());
		}
		Field fieldUserName = userClass.getDeclaredField("name");
		// 取消安全性检查,设置后才可以获取或者修改private修饰的属性,也可以批量对所有属性进行设置
		fieldUserName.setAccessible(true);
		fieldUserName.set(user, "Anglagdd");
		// 可以直接对 private 的属性赋值
		System.out.println("修改属性后对象:\t" + user);

		// User user = (User) userClass.newInstance();
		// 获取当前类的所有方法
		Method[] methods = userClass.getDeclaredMethods();
		// 获取公有方法(包括父类)
		// Method[] methods = userClass.getMethods();
		// 取消安全性检查,设置后才可以调用private修饰的方法,也可以单独对某个方法进行设置
		Method.setAccessible(methods, true);
		for (Method method : methods) {
			// 获取方法名和返回类型 获取参数类型:getParameterTypes
			System.out.println("方法名:" + method.getName() + " \t返回类型:" + method.getReturnType().getName());
		}
		// 获取无参方法
		Method getMethod = userClass.getDeclaredMethod("getName");
		// 取消安全性检查,设置后才可以调用private修饰的方法,也可以批量对所有方法进行设置
		getMethod.setAccessible(true);
		// 调用无参方法
		System.out.println("调用getName方法:" + getMethod.invoke(user));
		// 获取有参方法
		Method setMethod = userClass.getDeclaredMethod("setName", String.class);
		// 取消安全性检查,设置后才可以调用private修饰的方法,也可以批量对所有方法进行设置
		setMethod.setAccessible(true);
		// 调用有参方法
		System.out.println("调用setName方法:" + setMethod.invoke(user, "Angladdddd"));
		System.out.println("通过set方法修改属性后对象:\t" + user);

	}
}

 

<think>好的,用户想查找Java反射机制的代码示例,我需要根据提供的引用资料来组织回答。首先,我应该回顾用户提供的引用内容,看看里面有哪些相关的代码示例和关键点。 引用[1]提到反射可以动态访问和操作类、方法和属性,引用[2]详细列出了反射操作构造方法、属性和方法的示例,引用[3]解释了Class对象反射的基本原理,引用[4]则提到了动态调用方法的例子。这些资料应该能提供足够的代码示例。 接下来,我需要按照用户的要求,结构清晰地分步骤回答。用户可能希望看到如何获取Class对象、操作构造方法、访问属性、调用方法等方面的示例。每个部分都需要对应的代码,并且要符合中文回答的格式。同时,必须确保所有数学表达式正确使用$...$或$$...$$,但这个问题主要涉及代码,可能数学表达式不多,不过需要检查是否有需要的地方。 然后,生成相关问题。问题应围绕反射机制的应用场景、优缺点、安全限制等方面,确保每个问题都与主题相关,并且能引导用户进一步学习。 最后,要确保引用正确,每个引用出现的部分末尾加上对应的标识,比如[^1]、[^2]等。需要检查是否有遗漏的引用,并正确对应到内容中提到的部分。 现在开始组织内容,首先介绍反射机制的基本概念,引用[1]和[3]中的内容。然后分步骤展示代码示例,每个步骤对应引用中的不同部分,比如构造方法、属性、方法等。代码部分需要用代码块包裹,并注明语言类型。同时,确保代码示例正确,符合用户提供的引用中的示例,比如引用[2]中的无参和有参构造方法操作,属性的访问,方法的调用等。 可能需要注意用户提到的“系统级指令”中的要求,比如行内数学表达式,但这里主要涉及代码,可能较少需要数学公式,不过如果有的话,比如提到方法参数数量等,可能需要用$...$包裹,例如方法有$n$个参数。需要检查是否有这种情况。 最后,生成相关问题,如反射的应用场景、优缺点、与内省的区别、安全限制等,确保问题覆盖用户可能关心的其他方面,并且基于提供的引用内容,例如引用[1]提到运行时分析和操作类,引用[4]提到动态调用方法,这些都可以作为相关问题的基础。 总结来说,回答需要结构清晰,分步骤提供代码示例,正确引用资料,并生成相关问题,同时符合所有格式要求。</think>### Java反射机制代码示例详解 Java反射机制允许在运行时动态分析或操作类、方法和属性,以下通过具体代码示例逐步说明其核心功能[^1][^3]。 --- #### **1. 获取Class对象** 反射操作的第一步是获取类的`Class`对象: ```java // 通过类名获取 Class<?> clazz1 = Class.forName("java.lang.String"); // 通过对象获取 String str = "Hello"; Class<?> clazz2 = str.getClass(); // 通过类字面量获取 Class<?> clazz3 = String.class; ``` --- #### **2. 操作构造方法** 通过反射创建对象实例: ```java // 无参构造 Class<?> userClass = Class.forName("com.example.User"); Object user1 = userClass.newInstance(); // 有参构造(需指定参数类型) Constructor<?> constructor = userClass.getConstructor(String.class, int.class); Object user2 = constructor.newInstance("Alice", 25); ``` *说明:`newInstance()`方法已废弃,推荐使用`getDeclaredConstructor().newInstance()`。* --- #### **3. 访问类属性** 动态读写对象的字段值: ```java // 获取public字段 Field publicField = userClass.getField("publicName"); publicField.set(user2, "Bob"); // 获取private字段(需设置可访问性) Field privateField = userClass.getDeclaredField("age"); privateField.setAccessible(true); int age = (int) privateField.get(user2); ``` --- #### **4. 调用类方法** 动态执行对象的方法: ```java // 调用无参方法 Method method1 = userClass.getMethod("getName"); String name = (String) method1.invoke(user2); // 调用有参方法 Method method2 = userClass.getMethod("setName", String.class); method2.invoke(user2, "Charlie"); ``` --- #### **5. 动态代理(高级应用)** 通过反射实现接口的动态代理: ```java interface Service { void process(); } class ServiceImpl implements Service { public void process() { System.out.println("Processing..."); } } Service proxy = (Service) Proxy.newProxyInstance( Service.class.getClassLoader(), new Class[]{Service.class}, (proxyObj, method, args) -> { System.out.println("Before method"); return method.invoke(new ServiceImpl(), args); } ); proxy.process(); ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值