首页 > 其他分享 >反射

反射

时间:2022-08-26 14:16:59浏览次数:46  
标签:反射 java entity reflect public User example

反射

一、介绍

1.什么是反射

反射就是把Java类中的__各个成分(构造器、属性和方法)映射成一个个的Java对象__,即在运行状态中:

  1. 对于任意一个类,都能知道这个类的所有属性和方法
  2. 对于任意一个对象,都能调用它的任意一个属性和方法

这种动态获取信息以及动态调用对象发放的功能叫Java的发射机制。

2.为什么产生反射

Java是一门静态类型语言,变量的类型在编译之前就需要确定,限制了程序的灵活性。

3.什么时候使用反射

当你获取不到类只能拿到类的路径字符串的时候,可以通过反射创建对象。

// 正常创建对象
User user = new User();

但是如果只能获取到User类的路径,怎么创建对象?

String str = "com.example.reflect.entity.User";

※必须是全路径

方法如下:

Class clazz = Class.forName(str);
User user = (User) clazz.newInstance();

完整代码:

public class UserTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        // 只能获取字符串 如何创建对象?
        String str = "org.example.reflect.entity.User";
        // 利用反射
        Class clazz = Class.forName(str);
        User user = (User) clazz.newInstance();
        // --------
        user.setName("孟祥宽");
        user.setAge("18");
        user.show();
    }
}

运行结果:

image-20220825145322793

二、Class类介绍

Class类是Java反射机制的起源和入口,用于获取与类相关的各种信息,提供了获取类信息的相关方法。

1.创建Class对象

1.1 通过Class关键字

        // 方式一: 通过Class关键字
        Class<User> clazz = User.class;
        Object o = clazz.newInstance();
        System.out.println(o instanceof User);

运行结果:

image-20220825160035067

1.2 通过getClass()方法

// 方式二: 通过getClass方法
        User user = new User();
        Class<? extends User> clazz = user.getClass();
        Object o = clazz.newInstance();
        System.out.println(o instanceof User);

运行结果:

image-20220825160035067

1.3 通过forName()方法

 		String str = "org.example.reflect.entity.User";
        Class clazz = Class.forName(str);

2.Class类方法

// ---------------------- 获取构造器 ------------------
        // 只能获取public修饰的所有构造器 --- 子类
        Constructor<?>[] constructors = clazz.getConstructors();
        System.out.println("突破限制前的构造器:" + Arrays.toString(constructors));

        //突破限制 能获取非public修饰的所有构造器 --- 子类
        Constructor<?>[] constructors2 = clazz.getDeclaredConstructors();
        System.out.println("突破限制的构造器:" + Arrays.toString(constructors2));
        
        // 获取单一public修饰的构造器
        Constructor<? extends User> constructor = clazz.getConstructor();
        System.out.println("user里的public修饰的无参构造器:" + constructor);

        Constructor<? extends User> constructor2 = clazz.getDeclaredConstructor(String.class, int.class);
        System.out.println("user里的突破限制后的有参构造:" + constructor2);

        // 执行public修饰的构造器
        Object o1 = constructor.newInstance();

        constructor2.setAccessible(true);
        User o2 = constructor2.newInstance("孟祥宽", 18);
        System.out.println(o2.toString());

        // -----------------------------------------------------
        

        // ---------------- 获取字段 -----------------------
        // 只能获取public修饰的所有字段 --- 子类和父类
        Field[] fields = clazz.getFields();
        System.out.println("突破限制前获取的属性:" + Arrays.toString(fields));

        // 突破限制 能获取非public修饰的所有属性 --- 子类
        Field[] fields2 = clazz.getDeclaredFields();
        System.out.println("突破限制获取的属性:" + Arrays.toString(fields2));
        
        // 获取public修饰的单一的属性 --- 子类和父类
        Field dh = clazz.getField("dh");
        System.out.println("user里的一个属性:" + dh);
        // 获取非public修饰的单一的属性 --- 子类
        Field age = clazz.getDeclaredField("age");
        System.out.println("user里突破限制后获取的属性:" + age);

        // 给属性赋值
        dh.set(o1, "18943130289");

        age.setAccessible(true);
        age.set(o1, 18);
        // -----------------------------------------------
        
        
        // ------------------ 获取方法 ---------------------
        // 只能获取public修饰的所有方法 --- 子类和父类
        Method[] methods = clazz.getMethods();
        System.out.println("突破限制前获取的方法:" + Arrays.toString(methods));

        // 突破限制 能获取非public修饰的所有方法 --- 子类
        Method[] methods2 = clazz.getDeclaredMethods();
        System.out.println("突破限制获取的方法:" + Arrays.toString(methods2));

        // 获取单个的方法 -- 子类和父类
        Method setAge = clazz.getMethod("setAge", int.class);
        System.out.println("user里的public修饰的方法:" + setAge);

        // 获取非public修改时的方法
        Method say = clazz.getDeclaredMethod("say");
        System.out.println("user突破限制获取的方法:" + say);

        // 执行方法
        setAge.invoke(o1, 20);
        System.out.println(o1.toString());

        say.setAccessible(true);
        say.invoke(o1);
        // -------------------------------------------------
        
        // ------------------------- 获取有泛型的属性或者方法中的泛型 -------------------------------
        Field nums = clazz.getDeclaredField("nums");
        Type genericType = nums.getGenericType();
        System.out.println("泛型" + genericType);
        Class<?> type = nums.getType();
        System.out.println(type);

        Method getNums = clazz.getMethod("getNums");
        Type genericParameterTypes = getNums.getGenericReturnType();
        System.out.println("方法中的泛型:" + genericParameterTypes);

运行结果:

突破限制前的构造器:[public org.example.reflect.entity.User(java.lang.String,java.lang.String,java.lang.String,java.lang.String,int), public org.example.reflect.entity.User()]
突破限制的构造器:[private org.example.reflect.entity.User(java.lang.String,int), public org.example.reflect.entity.User(java.lang.String,java.lang.String,java.lang.String,java.lang.String,int), public org.example.reflect.entity.User()]
user里的public修饰的无参构造器:public org.example.reflect.entity.User()
user里的突破限制后的有参构造:private org.example.reflect.entity.User(java.lang.String,int)
User{name='孟祥宽', age=18, xb='null', dh='null'}
突破限制前获取的属性:[public java.lang.String org.example.reflect.entity.Person.dh]
突破限制获取的属性:[private java.lang.String org.example.reflect.entity.User.name, private int org.example.reflect.entity.User.age, private java.util.Map org.example.reflect.entity.User.nums]
user里的一个属性:public java.lang.String org.example.reflect.entity.Person.dh
user里突破限制后获取的属性:private int org.example.reflect.entity.User.age
突破限制前获取的方法:[public java.lang.String org.example.reflect.entity.User.toString(), public java.lang.String org.example.reflect.entity.User.getName(), public void org.example.reflect.entity.User.setName(java.lang.String), public void org.example.reflect.entity.User.setAge(int), public int org.example.reflect.entity.User.getAge(), public java.util.Map org.example.reflect.entity.User.getNums(), public void org.example.reflect.entity.User.setNums(java.util.Map), public void org.example.reflect.entity.User.show(), public java.lang.String org.example.reflect.entity.Person.getDh(), public void org.example.reflect.entity.Person.setMz(java.lang.String), public void org.example.reflect.entity.Person.setXb(java.lang.String), public void org.example.reflect.entity.Person.setDh(java.lang.String), public java.lang.String org.example.reflect.entity.Person.getMz(), public java.lang.String org.example.reflect.entity.Person.getXb(), public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
突破限制获取的方法:[public java.lang.String org.example.reflect.entity.User.toString(), public java.lang.String org.example.reflect.entity.User.getName(), public void org.example.reflect.entity.User.setName(java.lang.String), public void org.example.reflect.entity.User.setAge(int), private void org.example.reflect.entity.User.say(), public int org.example.reflect.entity.User.getAge(), public java.util.Map org.example.reflect.entity.User.getNums(), public void org.example.reflect.entity.User.setNums(java.util.Map), public void org.example.reflect.entity.User.show()]
user里的public修饰的方法:public void org.example.reflect.entity.User.setAge(int)
user突破限制获取的方法:private void org.example.reflect.entity.User.say()
User{name='null', age=20, xb='null', dh='18943130289'}
我是user私有的方法
泛型java.util.Map<java.lang.String, java.lang.Integer>
interface java.util.Map
方法中的泛型:java.util.Map<java.lang.String, java.lang.Integer>

标签:反射,java,entity,reflect,public,User,example
From: https://www.cnblogs.com/mxkgmn/p/16627335.html

相关文章

  • 反射案例以及注解的概念
    反射案例需求:写一个"框架",可以帮我们创建任意类的对象,并且执行其中的任意方法实现:实现文件反射,步骤:将需要创建对象的全类名和需要......
  • 反射-Class对象功能获取Constructor以及Method
    Class对象功能_获取ConstructorConstructor构造方法:创建对象:TnewInstance(Object…initargs)如果使用空参数构造方法创建对象,操作可以简化:Class......
  • Java Servlet 入门:问题系列:反射方法参数名获取不到问题:arg0,arg1
    问题:获取反射的方法参数名时,得到arg0,arg1,而不是定义的参数名。示例代码:Parameter[]parameters=methodInfo.getParameters();if(parameters!=null&&parame......
  • 反射-Class对象功能概述以及获取Field
    Class对象功能概述1、获取成员变量们:Field[]getFields():获取所有public修饰的成员变量FieldgetField(Stringname):获取指定名称的public修饰的成员变量 Field[]g......
  • java中的注解和反射
    1什么是注解(1)定义:Annotation是从Jdk5.0开始后才引入的,不是程序本身,可以对程序作出解释。可以被其他程序读取(2)注解的使用:可以在package,class,method,field上面使用,......
  • 面试---反射
    ☺面试聊聊反射机制?Java的反射机制:是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个......
  • 反射机制
    反射机制(Reflection)1.静态与动态语言静态语言:运行时结构不可变的语言,如Java、C、C++。动态语言:运行时可以改变其结构的语言,如C#、JavaScript、PHP、Python等。Java不是......
  • golang反射reflect
    1reflect包reflect包实现了运行时反射,允许程序操作任意类型的对象。典型用法是用静态类型interface{}保存一个值,通过调用TypeOf获取其动态类型信息,该函数返回一个Type类......
  • C++反序列化--一种基于class infomation反射库的反序列化数据结构
    序列化与反序列化概念:将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的另一台计算机上以实现通讯。这个将程序数据转化成能被存储并传输的格式的......
  • Java的反射
    在我们平时的开发中,我们肯定会遇到过spring框架。框架中我们几乎不需要手动去new对象。只需要通过一些简单的配置,spring就会把对象为我们创建好。这里就用到反射。下面我......