java 反射

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
	}
}
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值