Java 反射获取类实例的4种方式、创建对象、调用构造器、属性或方法

1、在编译的时候不确定用哪个属性或方法时,则可以使用反射

2、getDeclared系列方法:

  • 可以获取当前运行时类及其父类中声明为 public 访问权限的属性或方法
  • 获取当前运行时类中声明为 public 的构造器(不包含父类)

3、非Declared系列方法:

  • 可以获取当前运行时类中声明的所有属性、方法或构造器(不包含父类);当遇到私有结构时,先执行 setAccessible(true) 方法就可以访问了,否则会报错。
java">public class Person {
    private String name;
    public int age;
    public String nation;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(String name, int age, String nation) {
        this.name = name;
        this.age = age;
        this.nation = nation;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getNation() {
        return nation;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setNation(String nation) {
        this.nation = nation;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", nation='" + nation + '\'' +
                '}';
    }
    public void show() {
        System.out.println(this);
    }
}
java">import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
//        Person p1 = new Person("Tom", 12, "中国");

        //通过反射,创建运行时类对象
        Class clazz = Person.class;// or Class<Person> clazz = Person.class;
        Constructor cons = clazz.getConstructor(String.class, int.class);
        Person p1 = (Person) cons.newInstance("Tom", 14);
        System.out.println(p1);
        //getConstructors(): 获取当前运行时类中声明为public的构造器(不包含父类构造器)
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor c: constructors) {
            System.out.println(c);
        }
        //getDeclaredConstructors(): 获取当前运行时类中声明的所有构造器
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for (Constructor c: declaredConstructors) {
            System.out.println(c);
        }


        //getFields(): 获取当前运行时类及其父类中声明为public访问权限的属性
        Field[] fields = clazz.getFields();
        for (Field f: fields) {
            System.out.println(f);
        }
        //getDeclaredFields(): 获取当前运行时类中声明的所有属性(不包含父类)
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field f: declaredFields) {
            System.out.println(f);
        }
        //getDeclaredField(属性名称): 通过反射,调用对象指定的属性
        Field age = clazz.getDeclaredField("age");
        if(!age.isAccessible()) {
            age.setAccessible(true);//设置为可访问,否则私有属性不可访问
        }
        age.set(p1, 10);
        System.out.println(p1);


        //getMethods(): 获取当前运行时类及其父类中声明为public访问权限的方法
        Method[] methods = clazz.getMethods();
        for (Method method: methods) {
            System.out.println(method);
        }
        //getDeclaredMethods(): 获取当前运行时类中声明的所有方法(不包含父类)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method method: declaredMethods) {
            System.out.println(method);
        }
        //getDeclaredMethod(方法名称): 通过反射,调用对象指定的方法
        Method show = clazz.getDeclaredMethod("show");
        if(!show.isAccessible()){
            show.setAccessible(true);//设置为可访问,否则私有方法不可访问
        }
        show.invoke(p1);


        //获取类实例的4种方式
        //方式一:.class(有限制:编译时就把要调用的类名确定了)
        Class clazz1 = Person.class;
        System.out.println(clazz1);//class reflectTest.Person
        //方式二:通过运行时类对象(有限制:提前是本身就有该类的对象)
        Person p = new Person("Tom", 12);
        Class clazz2 = p.getClass();
        System.out.println(clazz2);//class reflectTest.Person
        //方式三:调用class的静态方法(常用)
        Class clazz3 = Class.forName("reflectTest.Person");
        System.out.println(clazz3);//class reflectTest.Person
        //方式四:使用类的加载器:ClassLoader(不常用)
        ClassLoader classLoader = ReflectTest.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("reflectTest.Person");
        System.out.println(clazz4);//class reflectTest.Person
    }
}


http://www.niftyadmin.cn/n/5160859.html

相关文章

从零开始搭建微服务(二)

忘记了软件还没有装全,今天先把所有的软件装上,nacos已经装过了我们就不在装了,剩余的软件全部都是通过docker安装,我在centos7里面 1. 安装docker 安装dockeryum -y install docker开机自启 systemctl enable docker启动dockre systemctl start docker查看docker版本 doc…

MATLAB算法实战应用案例精讲-【图像处理】Transformer

目录 前言 算法原理 什么是transformer呢? self-attention 输入和位置编码 编码器 Softmax

C#开源项目:私有化部署LLama推理大模型

推荐一个C#大模型推理开源项目&#xff0c;让你轻松驾驭私有化部署&#xff01; 01 项目简介 LLama是Meta发布的一个免费开源的大模型&#xff0c;是一个有着上百亿数量级参数的大语言模型&#xff0c;支持CPU和GPU两种方式。 而LLamaSharp就是针对llama.cpp封装的C#版本&am…

OpenFeign讲解+面试题

一&#xff1a;OpenFeign是什么&#xff1f; 是一个声明式的web客户端,只需要创建一个接口,添加注解即可完成微服务之间的调用 二&#xff1a;调用微服务的方式&#xff1f; ribbon restTemplate方式调用openFeign通过接口注解的方式调用 三&#xff1a;如何使用OpenFeign&…

Xcode15更新内容

参考博客&#xff1a; 【WWDC 2023】Xcode 15 更新内容 文章目录 1. xcode15起&#xff0c;项目内创建的图片可以使用点语法访问2.2. UIKit项目也可以使用预览功能3. Xcode新增标签功能4.Log分类 1. xcode15起&#xff0c;项目内创建的图片可以使用点语法访问 2.2. UIKit项目也…

Git查询某次提交属于哪个分支

在Android studio&#xff08;JetBrains系列也类似&#xff09;左下角&#xff0c;可以看到所有提交信息。 选中某一次提交信息&#xff0c;右键&#xff0c;选择“Copy Revision Number”&#xff0c;如下图&#xff1a; 打开Android studio的Terminal&#xff0c;输入git b…

SSL证书有免费的吗?

SSL证书是什么&#xff1f; SSL全称: Secure Socket Layer Certificate&#xff0c;中文全称:安全套接字层证书。是一种由数字证书颁发机构(CA) 签发的数字证书。它用于建立安全的加密连接&#xff0c;确保通过网络传输的数据在客户端和服务器之间的安全性和完整性。 SSL证书的…

出现 Daemons using outdated libraries 的解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 使用apt安装某些包的时候,弹出如下界面: Daemons using outdated libraries的选择框 并问我需要重启的服务,which services should be restarted? 不知什么情况,选择esc之后,所安装的包并没有成功!于是深入剖析 2.…