一、反射的概念
反射机制 : 将类的各个部分 组成一个新的对象(Class 对象) 就是反射机制
反射使用场景: A.框架 B.热修复…
- 反射是所有框架的灵魂 所有的框架都使用了反射技术
Java中所有的类在反射面前都是裸体(通过反射可以获取到所有的资源)
二、获取反射对象
- 第一种方法: 通过 对象名.getClass() 这种方式使用的比较少
- 第二种方式: 通过 类名.class 来获取
- 第三种方式: Class.forName(“完整的包名+类名”) 这种方式比较常用
代码:
import org.junit.Test;
//获取学生类反射对象
public class Test01 {
@Test
public void showInfo01() throws ClassNotFoundException {
//第一种
Student stu = new Student();
Class cla = stu.getClass();
System.out.println(cla);
//第二种方式
Class cla01 = Student.class;
System.out.println(cla01);
//第三种方式
Class cla02 = Class.forName("com.ahao.Student");
System.out.println(cla02);
}
}
三、 获取构造方法
方法的名称 | 方法的描述 |
---|---|
public Constructor<?>[] getConstructors() | 获取所有的公有的构造方法 |
public Constructor<?>[] getDeclaredConstructors() | 获取所有的构造方法(包括私有的) |
public Constructor getConstructor(Class<?>… parameterTypes) | 获取单个公有的构造方法 |
public Constructor getDeclaredConstructor(Class<?>… parameterTypes) | 获取单个私有的构造方法 |
代码-学生类
package com.ahao.demo05;
public class Student {
public String name;
private int age;
public Student(){
}
private Student(String name){
System.out.println(name);
}
public void showInfo(){
System.out.println("哈哈哈哈哈");
}
private void show(String s){
System.out.println(s);
}
}
代码:
@Test
public void showInfo02() throws ClassNotFoundException {
//获取到Class对象
Class cla = Class.forName("com.ahao.Student");
//获取所有公有的构造方法
Constructor[] cons = cla.getConstructors();
for (Constructor c : cons) {
System.out.println(c);
}
}
代码:
@Test
public void showInfo03() throws ClassNotFoundException {
//获取到Class对象
Class cla = Class.forName("com.ahao.Student");
//获取所有公有的构造方法
Constructor[] cons = cla.getDeclaredConstructors();
for (Constructor c : cons) {
System.out.println(c);
}
}
代码:
@Test
public void showInfo04() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取到Class对象
Class cla = Class.forName("com.ahao.Student");
//获取单个公有的构造方法
Constructor con = cla.getConstructor();
System.out.println(con);
//通过反射来实例化对象 Student stu = new Student()
Student stu = (Student) con.newInstance();
stu.showInfo();
}
代码:
@Test
public void showInfo05() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取到Class对象
Class cla = Class.forName("com.ahao.Student");
//获取私有的单个构造方法
Constructor con = cla.getDeclaredConstructor(String.class);
//使用暴力反射去除私有
con.setAccessible(true);
System.out.println(con);
//通过反射来实例化对象 Student stu = new Student()
Student stu = (Student) con.newInstance("ahao");
//stu.showInfo();
}
四、获取成员方法
方法 的名称 | 方法的描述 |
---|---|
public Method[] getMethods() | 获取所有的公有的方法(包括父类公有的方法) |
public Method[] getDeclaredMethods() | 获取所有的方法(包括私有) |
public Method getMethod(String name, Class<?>… parameterTypes) | 获取单个公有的方法 |
public Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 获取单个私有的方法 |
代码
@Test
public void showInfo() throws ClassNotFoundException {
Class cla = Class.forName("com.ahao.Student");
Method[] methods = cla.getMethods();
for (Method m :methods) {
System.out.println(m);
}
}
代码
@Test
public void showInfo01() throws ClassNotFoundException {
Class cla = Class.forName("com.ahao.Student");
Method[] methods = cla.getDeclaredMethods();
for (Method m :methods) {
System.out.println(m);
}
}
代码
@Test
public void showInfo02() throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
Class cla = Class.forName("com.ahao.Student");
//获取单个公有方法
Method met = cla.getMethod("showInfo");
//获取公有构造方法
Constructor con = cla.getConstructor();
//实例化对象
Object obj = con.newInstance();
//调用方法
met.invoke(obj);
}
代码
@Test
public void showInfo03() throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
Class cla = Class.forName("com.ahao.Student");
//获取单个私有方法
Method met = cla.getDeclaredMethod("show",String.class);
//使用暴力反射去除私有
met.setAccessible(true);
//获取公有构造方法
Constructor con = cla.getConstructor();
//实例化对象
Object obj = con.newInstance();
//调用方法
Object o = met.invoke(obj,"阿豪");
System.out.println(o);
}
五、案例
5.1 利用反射来忽略集合泛型
需求 利用反射来忽略集合泛型
分析
1.List<String> li = new ArrayList<>()
2.调用集合的方法 add() ===>只能存String类型的数据
3.利用反射来获取add方法
public Method getMethod("就是方法的名称",Object.class)
4.调用方法进行赋值
代码
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Test01 {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
List<String> li = new ArrayList<>();
//li.add("牛逼");
li.add(34)
//获取当前对象的class
Class cla = li.getClass();
//获取方法
Method m = cla.getMethod("add", Object.class);
//调用方法
m.invoke(li,11);
for (Object obj : li){
System.out.println(obj);
}
}
}
5.2 案例-加载配置文件
step04 在配置文件编写内容
classname=com.ahao.demo07.Student
methodname=show
par=String,int,String
step05 读取properties文件的工具类
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesUtils {
//私有的属性
private static PropertiesUtils propertiesUtils;
private Properties p;
//私有构造
private PropertiesUtils(){
try {
p = new Properties();
//通过反射来加载配置文件
InputStream is = PropertiesUtils.class.getResourceAsStream("admin.properties");
p.load(is);
} catch (IOException e) {
e.printStackTrace();
}
}
//公有的方法
public static synchronized PropertiesUtils getInstance(){
if (propertiesUtils ==null){
propertiesUtils = new PropertiesUtils();
}
return propertiesUtils;
}
/**
* 根据键来获取值
* @param key
* @return
*/
public String getValue(String key) {
return p.getProperty(key);
}
}
step06 测试类
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Test01 {
@Test
public void showTest() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException {
String classname = PropertiesUtils.getInstance().getValue("classname");
String methodname = PropertiesUtils.getInstance().getValue("methodname");
//获取class对象
Class cla = Class.forName(classname);
//获取构造方法
Constructor con = cla.getConstructor();
//实例化对象
Object o = con.newInstance();
Class[] classes = showClass();
if (classes ==null || classes.length <=0){
//获取方法
Method m = cla.getMethod(methodname);
//调用方法
m.invoke(o);
}else{
Method m = cla.getMethod(methodname,classes);
m.invoke(o,"阿豪",18,"女");
}
}
public Class[] showClass(){
String par = PropertiesUtils.getInstance().getValue("par");
//对字符串进行判断 表示没有参数
if (par ==null ||"".equals(par)){
return null;
}
//使用集合存储
List<Class> li = new ArrayList<>();
String[] arrays = par.split(",");
for (String s :arrays) {
if (s.equals("String")){
li.add(String.class);
}else if (s.equals("int")){
li.add(int.class);
}else {
li.add(Object.class);
}
}
return li.toArray(new Class[li.size()]);
}
}
六、 反射获取成员变量
方法名称 | 方法的说明 |
---|---|
public Field[] getFields() | 获取公有的成员变量 |
public Field[] getDeclaredFields() | 获取所有的成员变量 |
public Field getField(String name) | 获取单个成员变量 |
public Field getDeclaredField(String name) | 获取私有的成员变量 |
代码
//获取Class对象
Class cla = Class.forName("com.ahao.demo01.Student");
//获取成员变量
Field[] fields = cla.getFields();
for (Field f : fields) {
System.out.println(f);
}
代码
Class cla = Class.forName("com.ahao.demo01.Student");
//获取所有的成员变量
Field[] fields = cla.getDeclaredFields();
for (Field f :fields){
System.out.println(f);
}
代码
Class cla = Class.forName("com.ahao.demo01.Student");
//获取单个公有的成员变量
Field f =cla.getField("name");
//获取构造方法
Constructor con = cla.getConstructor();
//实例化对象
Object o = con.newInstance();
//设置成员变量值
f.set(o,"阿豪");
System.out.println(f.get(o));
代码
Class cla = Class.forName("com.ahao.demo01.Student");
//获取单个公有的成员变量
Field f =cla.getDeclaredField("age");
//使用暴力反射去除私有
f.setAccessible(true);
//获取构造方法
Constructor con = cla.getConstructor();
//实例化对象
Object o = con.newInstance();
//设置成员变量值
f.set(o,18);
System.out.println(f.get(o));