Java反射

一、反射的概念

反射机制 : 将类的各个部分 组成一个新的对象(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));

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值