java 反射

本文深入介绍了Java反射机制的基础知识,包括如何获取Class对象、实例化对象、获取类的方法和属性等内容,并提供了丰富的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Class<T>类(在java.lang包中,Instances of the class Classrepresent classes and interfaces in a running Javaapplication):在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。
T - 由此 Class 对象建模的类的类型。例如,String.class 的类型是Class<String>。如果将被建模的类未知,则使用 Class<?>。
User类
package com.test.reflect;

/**
 * @author cxl
 * 2013-10-26
 */
public class User {
	
	private String name;
	private int age;
	
	public User() {
		
	}
	
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		System.out.println("getter name is " + this.name);
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
		System.out.println("setter name is " + name);
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [age=" + age + ", name=" + name + "]";
	}
	
	public String getCountryInfo(String country) {
		return "I come from " + country;
	}
	
	private String sayHello(String name) {
		return "hello," + name;
	}
}
获取Class类的对象
一、通过getClass()方法获取
利用对象调用getClass()方法获取该对象的Class实例;
二、通过forName()方法获取
使用Class类的静态方法forName(),用类的名字获取一个Class实例
三、通过类.class方式获取
使用类.class方式Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例
DemoClass类
import com.test.reflect.User;


public class DemoClass {
	public static void main(String[] args) throws Exception {
		User u = new User();
		// 1.通过getClass()方法获取
		Class<?> userClass1 = u.getClass();
		System.out.println(userClass1.getName());//com.test.reflect.User
		// 2.通过forName()方法获取
		Class<?> userClass2 = Class.forName("com.test.reflect.User");
		System.out.println(userClass2.getName());//com.test.reflect.User
		// 3.通过类.class方式获取
		Class<?> userClass3 = User.class;
		System.out.println(userClass3.getName());//com.test.reflect.User
		// 基础类型.class方式
		Class<?> userClass4 = int.class;
		System.out.println(userClass4.getName());//int
		// 基础类型包装类.TYPE获取
		Class<?> userClass5 = Integer.TYPE;
		System.out.println(userClass5.getName());//int
		// 基础类型包装类.class
		Class<?> userClass6 = Integer.class;
		System.out.println(userClass6.getName());//java.lang.Integer
	}
}
 获取相应类的实例化对象
DemoInstance类
import java.lang.reflect.Constructor;

import com.test.reflect.User;

public class DemoInstance {
	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		//获取所有构造方法
		Constructor<?>[] constructors = userClass.getConstructors();
		for (Constructor<?> constructor : constructors) {
			System.out.println(constructor);
			//public com.test.reflect.User(java.lang.String,int)
			//public com.test.reflect.User()
		}
		//一、根据指定的构造方法实例化对象
		//1.通过无参的构造方法实例化对象
		User user = (User)userClass.newInstance();
		user.setName("hello");//setter name is hello
		user.setAge(25);
		user.getName();//getter name is hello
		System.out.println(user);//User [age=25, name=hello]
		
		//2.通过有参的构造方法实例化对象
		Constructor<?> constructor = userClass.getConstructor(String.class,int.class);
		//Constructor<?> constructor = userClass.getConstructor(new Class[]{String.class,int.class});
		User u = (User)constructor.newInstance("world",27);
		//User u = (User)constructor.newInstance(new Object[]{"world",27});
		System.out.println(u);//User [age=27, name=world]
		
		//二、根据构造方法的数组实例化对象(注意得到构造方法的顺序)
		User u1 = (User)constructors[0].newInstance("cxl",25);
		System.out.println(u1);//User [age=25, name=cxl]
		User u2 = (User)constructors[1].newInstance();
		System.out.println(u2);//User [age=0, name=null]
	}
}
 获取class对象中的方法
import java.lang.reflect.Method;

public class DemoMethod {
	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		//1.getMethods()获取类public的方法(包括继承的方法)
		Method[] methods1 = userClass.getMethods();
		System.out.println("getMethods()获取的方法有:");
		for (Method method : methods1) {
			System.out.println(method);
		}
		//2.getDeclaredMethods()获取类的所有方法(但不包含继承的方法)
		System.out.println("getDeclaredMethods()获取的方法有:");
		Method[] methods2 = userClass.getDeclaredMethods();
		for(Method method : methods2){
			System.out.println(method);
		}
	}
}
 打印结果:
getMethods()获取的方法有:
public int com.test.reflect.User.getAge()
public void com.test.reflect.User.setAge(int)
public int com.test.reflect.User.add(int,int)
public java.lang.String com.test.reflect.User.toString()
public java.lang.String com.test.reflect.User.getName()
public void com.test.reflect.User.setName(java.lang.String)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public boolean java.lang.Object.equals(java.lang.Object)
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
getDeclaredMethods()获取的方法有:
public int com.test.reflect.User.getAge()
public void com.test.reflect.User.setAge(int)
public int com.test.reflect.User.add(int,int)
public java.lang.String com.test.reflect.User.toString()
public java.lang.String com.test.reflect.User.getName()
public void com.test.reflect.User.setName(java.lang.String)
 获取class对象中的属性 
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class DemoField {
	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		Field[] fields = userClass.getDeclaredFields();
		for (Field field : fields) {
			//获取属性
			System.out.println("属性 :" + field.getName());
			int mod = field.getModifiers();
			//获取属性修饰符
			System.out.println("属性修饰符 :" + Modifier.toString(mod));
			//获取属性类型
			System.out.println("属性类型:" + field.getType().getName());
			System.out.println(Modifier.toString(mod) + " " + 
					field.getType().getName() + " " + field.getName());
		}
	}
}
 打印结果:
属性 :name
属性修饰符 :private
属性类型:java.lang.String
private java.lang.String name
属性 :age
属性修饰符 :private
属性类型:int
private int age
 通过getFields()方法可以获取父类或者接口的public属性,getDeclaredFields()获得某个类的所有申明的属性,类似的方法有getConstructors()和getDeclaredConstructors(),getMethods()和getDeclaredMethods()。
通过getInterfaces()方法获取实现的接口,通过getSuperclass()方法获取继承类
通过反射调用方法
DemoInvoke类
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.test.reflect.User;

/**
 * 反射调用方法
 */
public class DemoInvoke {

	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		User user = (User) userClass.newInstance();
		/**
		 * 通过反射调用User类的普通方法 getMethod(String name, Class<?>... parameterTypes)
		 * name指调用的方法名 ,parameterTypes是指按声明顺序标识该方法入参类型的 Class对象的一个数组 可以通过
		 * new Class数组完成,如new Calss[]{String.class}{}中是入参类型的Class对象
		 */
		Method method = userClass.getMethod("getCountryInfo", String.class);
		String countryInfo = (String)method.invoke(user, "China");
		System.out.println(countryInfo);//I come from China
		
		/**
		 * 调用反射User类的setter,getter方法
		 */
		Field[] fields = userClass.getDeclaredFields();
		for (Field field : fields) {
			//属性
			String fieldName = field.getName();
			//setter方法名
			String setterName = "set" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			//getter方法名
			String getterName = "get" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			//获取setter方法
			Method setterMethod = userClass.getMethod(setterName,
					new Class[] {field.getType()});
			//获取getter方法
			Method getterMethod = userClass.getMethod(getterName,
					new Class[] {});
			System.out.println(field.getType().getSimpleName());//String int
			//setter方法
			if(field.getType().getName().equals("java.lang.String")) {
				setterMethod.invoke(user, "test");//setter name is test
			}
			if(field.getType().getName().equals("int")) {
				setterMethod.invoke(user, 25);
			}
			Object fieldValue = getterMethod.invoke(user);//getter name is test
			System.out.println("field : " + fieldName + " = " + fieldValue);
		}
		System.out.println(user);//User [age=25, name=test]
		
		DemoInvoke demoInvoke = new DemoInvoke();
		user = new User("lucy",18);
		User userCopy = (User)demoInvoke.copy(user);
		System.out.println(userCopy);//User [age=18, name=lucy]
	}
	
	/**
	 * 实现对User对象的拷贝
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	public Object copy(Object obj) throws Exception {
		
		//获取obj的Class对象
		Class<?> objClass = obj.getClass();
		
		//通过相应的Class对象的newInstance()new一个要返回的对象
		Object objCopy = objClass.newInstance();
		
		/*等价于Object objCopy = objClass.getConstructor(new Class[] {})
				.newInstance(new Object[] {});*/

		Field[] fields = objClass.getDeclaredFields();
		for (Field field : fields) {
			//属性
			String fieldName = field.getName();
			//setter方法名
			String setterName = "set" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			//getter方法名
			String getterName = "get" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			//获取setter方法
			Method setterMethod = objClass.getMethod(setterName,
					new Class[] { field.getType() });
			//获取getter方法
			Method getterMethod = objClass.getMethod(getterName,
					new Class[] {});
			//调用getter方法,得到传入的obj对象的属性值
			Object fieldValue = getterMethod.invoke(obj);
			//调用setter方法,设置objCopy对象的属性值为obj对象的属性值
			setterMethod.invoke(objCopy, new Object[]{fieldValue});
		}
		return objCopy;
	}
}
 访问私有成员变量及方法
DemoPrivate类
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.test.reflect.User;

public class DemoPrivate {
	public static void main(String[] args) throws Exception {
		Class<?> userClass = Class.forName("com.test.reflect.User");
		User user = (User) userClass.newInstance();
		
		//访问私有方法,注:通过getDeclaredMethod()方法获取method对象,不能通过getMethod()方法
		Method method = userClass.getDeclaredMethod("sayHello", String.class);
		//压制Java对访问修饰符的检查
		method.setAccessible(true);
		String sayInfo  = (String)method.invoke(user, "world");//hello,world
		System.out.println(sayInfo);

		//操作私有属性,注:通过getDeclaredField()方法获取method对象
		Field field = userClass.getDeclaredField("name");
		//压制Java对访问修饰符的检查
		field.setAccessible(true);
		field.set(user, "lily");
		System.out.println(field.get(user));//lily
	}
}
 
 
 
 
### Java反射机制使用教程及常见问题 Java反射机制是一种强大的工具,允许程序在运行时动态地检查和操作类、接口、字段和方法等内部信息[^1]。以下是关于Java反射机制的详细教程以及一些常见的问题。 #### 1. 反射机制的基本概念 Java反射机制是Java语言中一种动态访问、检测和修改自身的能力,主要作用是在运行时获取类的完整结构信息并对其进行操作[^2]。通过反射,可以实现以下功能: - 动态创建对象。 - 动态调用方法。 - 动态访问字段。 - 动态处理注解。 #### 2. 核心类与API Java反射的核心类位于`java.lang.reflect`包中,主要包括以下几类: - `Class`:表示类的运行时类对象,可以通过`Class.forName(String className)`或`Object.getClass()`获取。 - `Field`:表示类的成员变量。 - `Method`:表示类的方法。 - `Constructor`:表示类的构造方法。 #### 3. 使用示例 以下是一个简单的反射机制使用示例,展示了如何通过反射创建对象并调用方法。 ```java import java.lang.reflect.Method; public class ReflectionExample { public static void main(String[] args) throws Exception { // 获取目标类的Class对象 Class<?> cls = Class.forName("com.example.MyClass"); // 创建目标类的实例 Object obj = cls.getDeclaredConstructor().newInstance(); // 获取目标类的方法 Method method = cls.getMethod("myMethod", String.class); // 调用目标类的方法 method.invoke(obj, "Hello Reflection"); } } ``` #### 4. 性能问题 反射机制虽然强大,但在性能上存在一定的开销。例如,在大量调用反射方法时,其性能可能显著低于直接调用[^4]。因此,在实际开发中应权衡使用反射的必要性。 #### 5. 常见问题 - **安全性问题**:反射可以访问私有成员,这可能导致破坏封装性[^1]。 - **性能问题**:反射调用方法的性能比普通方法调用低[^4]。 - **异常处理**:反射操作容易抛出多种异常,如`ClassNotFoundException`、`NoSuchMethodException`等,需要妥善处理。 #### 6. 实际应用场景 Java反射机制在许多实际场景中发挥了重要作用,包括但不限于框架设计、动态代理、依赖注入、测试工具和序列化/反序列化等[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值