一、反射的概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。(源自网络)。
二、反射的用法__调用构造方法
javaBean
package com.limingming.reflect;
public class University {
int id;
String name;
public University(int id, String name) {
this.id = id;
this.name = name;
System.out.println("公共的构造方法");
}
protected University(int id) {
this.id = id;
System.out.println("受保护构造方法");
}
private University(String name) {
this.name = name;
System.out.println("私有的构造方法");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void showMessage(String param){
System.out.println("hahaha返给你一个妹子好不好。。。"+param);
}
}
测试类
package com.limingming.reflect;
import java.lang.reflect.Constructor;
/*
* 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;
*
* 1.获取构造方法:
* 1).批量的方法:
* public Constructor[] getConstructors():所有"公有的"构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
* 2).获取单个的方法,并调用:
* public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
* public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
*
* 调用构造方法:
* Constructor-->newInstance(Object... initargs)
*/
public class ConstructorTest{
public static void main(String[] args) throws Exception {
Class cla=Class.forName("com.limingming.reflect.University");
//获取所有public的构造方法
Constructor[] constructors=cla.getConstructors();
for (Constructor constructor:constructors){
System.out.println(constructor);
}
//获取单个构造方法
Constructor conPublic=cla.getConstructor(int.class,String.class);
//调用公共的构造方法
Object obj = conPublic.newInstance(1,"hahah");
//获取私有的构造方法 并调用
Constructor conPrivate = cla.getDeclaredConstructor(String.class);
//暴力访问忽略访问权限
conPrivate.setAccessible(true);
Object obj1 = conPrivate.newInstance("hahha");
}
}
getDeclaredConstructors() 方法 和 getDeclaredConstructor()方法的使用与上述相同不做概述
三、反射的用法__获取类属性并赋值
package com.limingming.reflect;
import java.lang.reflect.Field;
/*
* 获取成员变量并调用:
*
* 1.批量的
* 1).Field[] getFields():获取所有的"公有字段"
* 2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
* 2.获取单个的:
* 1).public Field getField(String fieldName):获取某个"公有的"字段;
* 2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
*
* 设置字段的值:
* Field --> public void set(Object obj,Object value):
* 参数说明:
* 1.obj:要设置的字段所在的对象;
* 2.value:要为字段设置的值;
*
*/
public class FieldTest {
public static void main(String[] args) throws Exception{
Class cla=Class.forName("com.limingming.reflect.University");
Field[] fields = cla.getFields();
for (Field field:fields){
System.out.println(field);
}
//为属性赋值
Object obj=cla.newInstance();
Field field = cla.getField("name");
field.set(obj,"hahahha");
//验证
University university=(University)obj;
System.out.println(university.name);
}
}
四、反射的用法__调用类的方法
package com.limingming.reflect;
import java.lang.reflect.Method;
/*
* 获取成员方法并调用:
*
* 1.批量的:
* public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
* public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
* 2.获取单个的:
* public Method getMethod(String name,Class<?>... parameterTypes):
* 参数:
* name : 方法名;
* Class ... : 形参的Class类型对象
* public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
*
* 调用方法:
* Method --> public Object invoke(Object obj,Object... args):
* 参数说明:
* obj : 要调用方法的对象;
* args:调用方式时所传递的实参;
*/
public class MethodTest {
public static void main(String[] args) throws Exception {
Class cla=Class.forName("com.limingming.reflect.University");
//获取所有公有方法包括 继承过来的
Method[] methods = cla.getMethods();
for (Method method:methods){
System.out.println(method);
}
//调用方法
Object object = cla.newInstance();
Method method = cla.getMethod("showMessage",String.class);
method.invoke(object,"妹子来了");
}
}
对于私有方法可使用setAccessible(true)方法暴力使用