欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java反射学习

程序员文章站 2024-01-21 14:33:16
...

反射:

定义
java程序可以加载一个运行时才得知其名称的class,并且获悉其完整构造(但是不包含methods)定义,并且生成其对象实体、或者其fields设置,或者唤醒其methods
功能:
在运行时判断一个对象所属的类
在运行时构造一个类的对象
在运行时判断任何一个雷所具有的成员变量和方法
在运行时调用一个对象的方法,生成动态代理
获取class的方法
类名称.class
对象.getclass
Class.forName(“cn.com.test”)通过类名称加载类,然后通过newInstance方法获取对象

Class<?>  c=Class.forName("learn.User");
Object obj = c.newInstance();
System.out.println(obj);

生成的结果为:

User [name=null, age=null, getName()=null, getAge()=null, getClass()=class learn.User, hashCode()=2065827189, toString()[email protected]]

可以看出生成了完整的构造,但是不包括方法的具体实现,需要注意的是newInstance时,如果你的类有有参构造函数,那么必须增加一个无参构造函数,不然无法构造出实例对象
User.java文件如下

package learn;

public class User {
	public  String name ;
	public  Integer    age;
	public User(String name_,Integer age_){
		name=name_;
		age=age_;
	}
	public User(){
		
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + ", getName()="
				+ getName() + ", getAge()=" + getAge() + ", getClass()="
				+ getClass() + ", hashCode()=" + hashCode() + ", toString()="
				+ super.toString() + "]";
	}
}

Field类的使用方法
(1)获取Field对象,

获取Field对象需要使用Class对象,下面是Class类的API:

Field getField(String name):通过名字获取公有成员变量的反射对象,包含父类中声明的公有成员变量;

Field[ ] getFields():获取所有公有成员变量反射对象,包含父类中声明的公有成员变量;

Field getDeclaredField(String name):通过名字获取本类中某个成员变量,包含本类的private成员变量,但父类中声明的任何成员变量都不包含;

Field[ ] getDeclaredFields():获取本类中声明的所有成员变量,包含private成员变量,但不包含父类中声明的任何成员变量;

(2)Field类的常用方法

String getName():获取成员变量名;

Class getDeclaringClass():获取成员变量的类型;

Class getType():获取当前成员变量的类型;

Object get(Object obj):获取obj对象的成员变量的值;

void set(Object obj, Object value):设置obj对象的成员变量值为value;

package learn;

import java.lang.reflect.Field;

public class Test {

	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException  {
		Class clazz=Class.forName("learn.User");
		User users = (User)clazz.newInstance();
		System.out.println(clazz);
        
		User user = new User("tom",11);
		User user1 = new User("liming",12);
		System.out.println(clazz.getFields()[0]);
		System.out.println(clazz.getFields()[1]);
		Field field1 = clazz.getField("name"); 
		Field field2 = clazz.getField("age") ;
		
		String username = (String)field1.get(user); 
		Integer password = (Integer)field2.get(user); 
		
		System.out.println(username + ", " + password);
		field1.set(user1, "xiaozhang");
		field1.set(user, "liSi"); 
		field2.set(user, 456); 
		
		System.out.println(user);
		System.out.println(user1);
		
	

	}
}

其结果为

class learn.User
public java.lang.String learn.User.name
public java.lang.Integer learn.User.age
tom, 11
User [name=liSi, age=456, getName()=liSi, getAge()=456, getClass()=class learn.User, hashCode()=2024711629, toString()[email protected]]
User [name=xiaozhang, age=12, getName()=xiaozhang, getAge()=12, getClass()=class learn.User, hashCode()=302478241, toString()[email protected]]

Constructor类使用方法
(1)获取Constructor对象

获取Construcator对象需要使用Class对象,下面API来自Class类:

Constructor getConstructor(Class… parameterTypes):通过指定的参数类型获取公有构造器反射对象;

Constructor[ ] getConstructors( ):获取所有公有构造器对象;

Constructor getDeclaredConstructor(Class… parameterTypes):通过指定参数类型获取构造器反射对象。可以是私有构造器对象;

Constructor[ ] getDeclaredConstructors():获取所有构造器对象。包含私有构造器;

(2)Construcator类常用方法

String getName():获取构造器名;

Class getDeclaringClass():获取构造器所属的类型;

Class[ ] getParameterTypes():获取构造器的所有参数的类型;

Class[ ] getExceptionTypes():获取构造器上声明的所有异常类型;

newInstance(Object… initargs):通过构造器反射对象调用构造器。

@Test
public  void test2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
	Class  clazz= Class.forName("learn.User");
	Constructor[] constructors = clazz.getConstructors();
	User user = (User)constructors[0].newInstance("tom",3);
	System.out.println(user.getAge());
	
}
//返回值为3

Method类
(1)获取Method

获取Method需要通过Class对象,下面是Class类的API:

Method getMethod(String name, Class… parameterTypes):通过方法名和方法参数类型获取方法反射对象,包含父类中声明的公有方法,但不包含所有私有方法;

Method[ ] getMethods():获取所有公有方法,包含父类中的公有方法,但不包含任何私有方法;

Method getDeclaredMethod(String name, Class… parameterTypes):通过方法名和方法参数类型获取本类中声明的方法的反射对象,包含本类中的私有方法,但不包含父类中的任何方法;

Method[ ] getDeclaredMethods( ):获取本类中所有方法,包含本类中的私有方法,但不包含父类中的任何方法。

(2)Method常用方法

String getName( ):获取方法名;

Class getDeclaringClass( ):获取方法所属的类型;

Class[ ] getParameterTypes( ):获取方法的所有参数的类型;

Class[ ] getExceptionTypes( ):获取方法上声明的所有异常类型;

Class getReturnType( ):获取方法的返回值类型;

Object invoke(Object obj, Object… args):通过方法反射对象调用方法,如果当前方法是实例方法,那么当前对象就是obj,如果当前方法是static方法,那么可以给obj传递null。args表示是方法的参数;

 public class Demo1 {
	@Test
	public void fun1() throws Exception {
		String className = "cn.ywq.User";
		Class clazz = Class.forName(className);
		Constructor c = clazz.getConstructor(String.class, String.class);
		User user = (User)c.newInstance("zhangSan", "123");
		
		Method method = clazz.getMethod("toString");
		String result = (String)method.invoke(user);
		System.out.println(result);
	}
}
相关标签: java 反射