java反射机制含义
在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,
都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调
用对象的方法的功能就称为java语言的反射机制。
java的反射机制作用
要想使用java的反射机制,首先我们要学会获得类的字节码文件。通过字节码文件,我们就能获得该类的属性和方法、类名、父亲类名,实现的接口等等信息。一个类字节码文件就对应着一个Class类型的对象,即字节码文件对象。
获取字节码对象
我们可以通过三种方式获得字节码文件对象
1. 通过Class demo1=Class.forName("全限定类名")来获取字节码文件对象,这种方式获取类的字节码文件对象时,该类还处于源文件,未编译成字节码文件。
2. 通过Class demo2=Demo.class获取字节码文件对象,这种获取方式,该类已经被编译成了字节码文件,也就是获取本身。
3. 通过Class demo3=demo.getClass()获取字节码文件对象,通过类的实例获取该类的字节码文件对象,该类处于创建对象阶段。
通过上述几种方法可以获取类的字节码对象,在使用时可以根据情况而定使用相应的获取方式,再获取到Class对象后,我们就能通过反射机制获取相应的一些信息。
通过反射机制获取信息
1、通过类字节码对象创建实例:
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//获取类的字节码对象
Class demo=Class.forName("demo.User");
//创建实例,通过User的无参构造函数创建实例
User user = (User) demo.newInstance();
}
2、获取构造器方法。通过类字节码对象创建实例只能通过无参构造函数创建实例,当需要通过有参构造函数创建实例时,可以通过该方法
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取类的字节码对象
Class demo=Class.forName("demo.User");
//获取指定的构造器
Constructor constructor = demo.getConstructor(String.class,int.class);
User zhangsan = (User) constructor.newInstance("zhangsan", 18);
}
3、 获取全部构造方法:
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取类的字节码对象
Class demo=Class.forName("demo.User");
//获取全部构造器
Constructor[] constructors = demo.getConstructors();
int k=1;
for (Constructor constructor :
constructors) {
//获取构造器中的全部参数的字节码对象
Class[] parameterTypes = constructor.getParameterTypes();
System.out.println("第"+k+++"个构造函数");
for(int i=0;i<parameterTypes.length;i++){
System.out.print(parameterTypes[i].getName()+",");
}
System.out.println();
}
}
4、、获取指定成员变量并使用和获取全部成员变量
//获取指定成员变脸
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//获取类的字节码对象
Class demo=Class.forName("demo.User");
//实例化对象
User user= (User) demo.newInstance();
user.setName("zhangsan");
//通过getField获取指定的成员变量
//如果时私有变量,则需要使用getDegetDeclaredField来获取
Field name = demo.getDeclaredField("name");
//将变量设置为可操作(私有变量不能在类外操作)
name.setAccessible(true);
//获取成员变量值
String sname =(String)name.get(user);
System.out.println(sname);
}
//获取全部成员变量并答应实例成员值
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//获取类的字节码对象
Class demo=Class.forName("demo.User");
//实例化对象
User user= (User) demo.newInstance();
user.setName("lisi");
user.setAge(18);
user.setPassword("258258");
//获取全部成员变量
Field[] declaredFields = demo.getDeclaredFields();
//遍历所有成员变量并答应实例成员变量值
for(Field field:declaredFields){
System.out.println(field.getName()+":"+field.get(user));
}
}
5、获取成员方法并调用和获取全部成员方法并调用
//获取指定成员变量并调用
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//获取类的字节码对象
Class demo=Class.forName("demo.User");
//实例化对象
User user= (User) demo.newInstance();
user.setName("lisi");
//若是私有方法则需要使用getDeclaredMethod(),公有则使用getFIeld即可
Method getName = demo.getMethod("getName");
//设置方法访问权限,若是共有方法可不写
getName.setAccessible(true);
System.out.println(getName.invoke(user));;
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//获取类的字节码对象
Class demo=Class.forName("demo.User");
//实例化对象
User user= (User) demo.newInstance();
user.setName("lisi");
user.setAge(18);
user.setPassword("258258");
//获取全部成员方法
Method[] declaredMethods = demo.getDeclaredMethods();
for (Method methos :
declaredMethods) {
System.out.println(methos.getName());
}
}