首页 > 编程语言 >Java反射

Java反射

时间:2024-03-01 15:46:35浏览次数:28  
标签:反射 Java String tester int class public Class

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

标签:反射,Java,String,tester,int,class,public,Class
From: https://www.cnblogs.com/icfh/p/18047232

相关文章

  • 初窥 java 变量【第一天】
    java变量2大类4小类8小种   基本数据类型整型byteshortintlong浮点型floatdouble字符型char布尔型boolean引用数据类型(未学) publicclassday1{publicstaticvoidmain(String[]args){//定义一个byte类型......
  • 反射和动态代理的联系
    动态代理和反射在Java编程中有一定的联系和相互补充的关系:综上所述,动态代理和反射在Java编程中常常结合使用,通过反射获取类的信息并利用动态代理创建代理对象,从而实现更灵活和动态的编程方式。联系:动态代理和反射都是在运行时进行操作的技术,能够在程序运行时动态地获取和操作类......
  • 写少一点/ARCHITECTURE/JavaScript类型转换/Logitech Options一直转圈
    《写少一点》https://www.yuque.com/beilo/simpread/1709260496568《ARCHITECTURE文件》https://www.yuque.com/beilo/simpread/1709260486335例子https://github.com/rust-lang/rust-analyzer/blob/d7c99931d05e3723d878bea5dc26766791fa4e69/docs/dev/architecture.md《Java......
  • Java匿名内部类 labmda表达式 传统风格 对比
    传统风格classMyInvocationHandlerimplementsInvocationHandler{   @Override   publicObjectinvoke(Objectproxy,Methodmethod,Object[]handlerArgs)throwsThrowable{       if("eat".equals(method.getName())){           System......
  • JavaScript事件
    键盘事件:keypress键盘事件,keyup抬起,keydown按下文档:load加载表单:focus获得焦点,blur失去焦点,submit提交事件,change改变事件其他:scroll滚动事件,selectstart选择事件1.event事件对象常见的属性和方法e.target返回触发事件的对象标准e.srcElement返回触发事件的对象......
  • 【转发】JAVA 线上故障排查完整套路,从 CPU、磁盘、内存、网络、GC 一条龙!
    线上故障主要会包括cpu、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如jstack、jmap等工具也是不囿于一个方面的问题的,基本上出问题就是df、free、top三连,然后依次jstack、jmap伺候,具体问题具体分析即可......
  • JavaScript基础
    引入方式JavaScript程序不能独立运行,它需要被嵌入HTML中,然后浏览器才能执行JavaScript代码。内部引入写在body结束标签的上方。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content=&......
  • Java 继承与多态:代码重用与灵活性的巧妙结合
    Java继承(子类和超类)在Java中,可以从一个类继承属性和方法到另一个类。我们将“继承概念”分为两类:子类(child):从另一个类继承的类超类(parent):被继承的类要从一个类继承,使用extends关键字。示例:classVehicle{protectedStringbrand="Ford";//Vehicle属性......
  • Java流程控制05:Switch选择结构
    Switch多选择结构1.多选择结构还有一个实现方式就是switchcase语句2. switchcase语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。3.switch语句中的变量类型可以是:3.1byte、short、int或者char3.2从JavaSE7开始......
  • JAVA案例:买飞机票
    packagecom.itheima.anli;publicclassAnli1{publicstaticvoidmain(String[]args){calculate(1000,8,"经济舱");System.out.println(calculate(1000,8,"经济舱"));}publicstaticdoublecalculate(doubleprice,i......