Java反射

Java反射

概念

Java反射指在程序执行时:

  • 对于类

​ 能够获得类的所有属性和方法

  • 对于对象

​ 能够通过对象调用它的任意一个方法和属性(包括私有的方法和属性)

这种动态获取并调用类的方法的机制称为Java反射

获取一个类

通过类名

包括查看类的静态变量以及通过完整类名获取

public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        // 通过查看静态变量
        Class cls = String.class;
        System.out.println(cls);

        // 通过一个类的完整类名获取
        Class cls2 = Class.forName("java.lang.String");
        System.out.println(cls2);
    }
}

image-20240301132538622

通过对象

通过对象的getClass方法

public class Main {
    public static void main(String[] args) throws ClassNotFoundException {

        String s = "test";
        Class cls = s.getClass();
        System.out.println(cls);
    }
}

访问类的字段

在Java中类字段对应的类型为Field

getFields()

获得某个类的所有public字段,包括父类中的public字段

import java.lang.reflect.Field;


class tester {

    static public int id = 2;

    public int getMoney() {		// getter方法
        return money;
    }

    private int money;
    protected int age;

    public String name;

    public String school;

}


public class Main {


    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        tester test = new tester();
        Class cls = test.getClass();


        Field id = cls.getField("id");
        System.out.println(id);         // public static int tester.id
        System.out.println(id.get(cls.newInstance()));  // 需要再创建实例 然后才能获取字段值
    }
}

getDeclaredFields()

        tester test2 = new tester();
        Field money = cls.getDeclaredField("money");
        money.setAccessible(true);	// 赋予权限
        money.set(test2, 666);
        System.out.println(test2.getMoney());	

访问类的方法

有如下四种方法

  • getMethod

获取某个publicMethod(包括父类)

public Method getMethod(String name, Class<?>... parameterTypes)
  • getDeclaredMethod

获取当前类的某个Method(不包括父类)

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
  • getMethods

获取所有publicMethod(包括父类)

  • getDeclaredMethods

获取当前类的所有Method(不包括父类)

import java.lang.reflect.Method;

class tester {

    static public int id = 2;

    public int getMoney() {
        return money;
    }

    private int money;
    protected int age;

    public String name;

    public String school;


    public void test1(){
        System.out.println("This is my test 1");
    }

    static public void test2(){
        System.out.println("This is my test 2");
    }
}


public class Main {


    public static void main(String[] args) throws Exception {
        tester test = new tester();
        Class testClass = test.getClass();

        Method m = testClass.getMethod("test1");
        m.invoke(test, null);

        Method m2 = testClass.getDeclaredMethod("test2");
        m2.invoke(test,null);
    }
}

获取构造方法

  • getConstructor

获取某个publicConstructor

public Constructor<T> getConstructor(Class<?>... parameterTypes)
  • getDeclaredConstructor

获取某个Constructor

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
  • getConstructors:获取所有publicConstructor

  • getDeclaredConstructors:获取所有publicConstructor

import java.lang.reflect.Constructor;

class tester {

    public tester(){
        System.out.println("无参构造方法");
    }

    public tester(String name){
        this.name = name;
        System.out.println("有参构造方法");
    }


    static public int id = 2;

    public int getMoney() {
        return money;
    }

    private int money;
    protected int age;

    public String name;

    public String school;


    public void test1(){
        System.out.println("This is my test 1");
    }

    static public void test2(){
        System.out.println("This is my test 2");
    }
}


public class Main {

    public static void main(String[] args) throws Exception {
        Class testClass = tester.class;        
        												// 有参的得加入参数的类型
        Constructor constructor = testClass.getConstructor(String.class);
        Object obj = constructor.newInstance("123");
        
        Constructor constructor1 = testClass.getConstructor();
        Object obj1 = constructor1.newInstance();
    }
}

image-20240301145048154

通过反射执行命令

  • 未使用反射
		Runtime.getRuntime().exec("calc");
  • 反射
        Class cls = Class.forName("java.lang.Runtime");
        Method m = cls.getMethod("exec", String.class);
        Method m2 = cls.getMethod("getRuntime");
        Object obj = m2.invoke(cls);
        m.invoke(obj,"calc");
  • 一句话版本
Class.forName("java.lang.Runtime").getMethod("exec", String.class).invoke(Class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(Class.forName("java.lang.Runtime")),"calc" );

总结

  • 获取类的⽅法: forName,getClass
  • 实例化类对象的⽅法: newInstance
  • 获取函数的⽅法: getMethod
  • 执行函数的⽅法: invoke
posted @ 2024-03-01 15:38  Icfh  阅读(5)  评论(0编辑  收藏  举报