java反射学习
反射:
定义:
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);
}
}
上一篇: 权限过滤器