首页 > 其他分享 >Reflection 反射

Reflection 反射

时间:2022-10-10 19:37:53浏览次数:45  
标签:反射 String System Class println out class Reflection

Reflection 反射

反射的基本概念

反射 就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对

应的方法

Class<?> aClass = Class.forName("mingyu.User");
Method setAge = aClass.getMethod("setAge", int.class);
Constructor<?> constructor = aClass.getConstructor();
User o = (User) constructor.newInstance();// 实例化
setAge.invoke(o,17);// 相当于 setAge(17);

java.long.reflect包

java.long.reflect包提供了反射中要用到的类,主要的类说明如下:

  • Constructor类:提供类的构造方法信息。
  • Field类:提供类或接口中成员的变量信息。
  • Method类:提供类或接口成员方法信息。
  • Array类:提供了动态创建和访问java数组的方法。
  • Modifier:提供类和成员访问修饰符信息。

image-20221010142823458

Class<String> a = String.class;
Class<?> a0 = String.class;
Class<?> a1 = Class.forName("java.lang.String");
Class<?> a2 = "".getClass();
Class<?> a3 = int[][].class;
Class<?> a4 = Class.class;
Class<?> a5 = String[].class;
Class<?> a6 = Object.class;
private int price;
public int getPrice(){
    return price;
}
public void setPrice(int price) {
    this.price = price;

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, 		      	 InvocationTargetException, InstantiationException, IllegalAccessException {
    // 正常的调用
    Ref03 r = new Ref03();
    r.setPrice(124);
    System.out.println(r.getPrice());
    // 使用反射调用
    Class<?> aClass = Class.forName("mingyu.Ref03");
    Method setPrice = aClass.getMethod("setPrice", int.class);
    Object o = aClass.getConstructor().newInstance();
    setPrice.invoke(o,123);
    Method getPrice = aClass.getMethod("getPrice");
    System.out.println(getPrice.invoke(o));
}
// 使用反射机制 打印出String类的所有方法
Class<String> a = String.class;
// Class b = new String().getClass();
// Method[] declaredMethods = a.getMethods();

Arrays.stream(a.getMethods()).forEach(System.out::println);
try {
    // 动态加载xx类的运行对象
    Class a = Class.forName("java.lang.String");
    // 获取成员方法的集合
    Method[] m = a.getDeclaredMethods();
    // 遍历成员方法的集合
    for (Method mm : m){
        // 打印权限修饰符、
        System.out.print(Modifier.toString(mm.getModifiers()));
        // 打印返回值类型名称
        System.out.print(" "+mm.getReturnType().getName()+" ");
        // 打印方法名称
        System.out.println(mm.getName()+"();");
    }
} catch (ClassNotFoundException e) {
    throw new RuntimeException(e);
}
public static void main(String[] args) throws  Exception{

    // java.sql.Connection 是不是接口
    System.out.println(Class.forName("java.sql.Connection").isInterface());//true

    System.out.println(Integer.class.isPrimitive());//false

    // 正常方式
    Book book = new Book();
    book.setName("木木");
    System.out.println(book.getName());

    // 反射方式
    Class<Book> bookClass = Book.class;
    Book book1 = bookClass.getConstructor().newInstance();
    // System.out.println(bookClass.getSimpleName());
    // System.out.println(bookClass.getName());
    // System.out.println(bookClass.getCanonicalName());
    // System.out.println(bookClass.getPackageName());
    // System.out.println(bookClass.getTypeName());
    // book1.info();
    Method setName = bookClass.getMethod("setName", String.class);
    Object s = setName.invoke(book1, "木木");
    Method getName = bookClass.getMethod("getName");
    System.out.println(getName.invoke(book1));

}
  • 获取类的class对象实例
Class clz = Class.forName("java.lang.String");
  • 根据Class对象实例获取Constructor对象
Constructor aop = clz.getConstructor();
  • 使用Constructor对象的newInstance方法获取反射类对象
Object obj = app.newInstance();

如果调用一个Method对象,则需要经过下面的步骤

  • 获取方法的 Method对象
Method setName = clz.getMethod("setName",String.Class);
  • 利用invoke方法调用方法
setName.invoke(obj,"木木");

反射常用API

获取反射中的Class对象

在反射中,要获取一个类或者调用一个类的方法,我们首先需要获取到该类的Class对象

java API中,获取Class类对象有三种方法

第一种,使用Class.forName()静态方法。当你知道该类的全路径名时,可以使用该方法获取Class对象。

Class cl = Class.forName("java.lang.String");

第二种,使用.class方法。

Class cl = Stirng.class;

第三种,使用类对象的getClass()方法。

String str = new String("Hello");
Class cl = str.getClass();

反射获取注解属性

(1).UserName.java 定义一个UserName注释类

package mingyu.demo;

import java.lang.annotation.*;

/**
 * @author Mxhlin
 * @Email [email protected]
 * @Date 2022/10/10/16:43
 * @Version
 * @Description 
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface UserName {
    String name() default "佚名";
}

(2)、User

/**
 * @author Mxhlin
 * @Email [email protected]
 * @Date 2022/10/10/16:47
 * @Version
 * @Description
 */
public class User {
    @UserName(name = "王五")
    private String name;

    public int pf (int i ){
        return i*i;
    }
}

(2)、Demo.java 读取User.class属性注解的内容

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author Mxhlin
 * @Email [email protected]
 * @Date 2022/10/10/16:54
 * @Version
 * @Description
 */
public class Demo {
    public static void main(String[] args) throws Exception{
        Class<User> userClass = User.class;

        // 反射读取类上的注解
        if (userClass.isAnnotationPresent(UserName.class)){
            UserName annotation = userClass.getAnnotation(UserName.class);
            System.out.println(annotation.name());
        }

        // 读取属性上的注解
        Field f = userClass.getDeclaredField("name");
        if (f.isAnnotationPresent(UserName.class)){
            UserName annotation = f.getAnnotation(UserName.class);

            System.out.println(annotation.name());
        }

        // 读取方法上的注解
        User u = new User();
        u.pf(2);
        Method pf = userClass.getDeclaredMethod("pf", int.class);
        if (pf.isAnnotationPresent(UserName.class)){
            System.out.println(pf.getAnnotation(UserName.class).name());
        }
    }
}
输出String里的方法

第一种

    public static void main(String[] args) {
        Class<String> a = String.class;
        int i =0;
        Arrays.stream(a.getMethods()).forEach(e->{
            System.out.println(e);
        });
    }

第二种

    public static void main(String[] args) {
        Class<String> a = String.class;// 使用反射获取Class类
        Method[] arr = a.getDeclaredMethods();// 获取声明所有方法
        StringBuilder sb = new StringBuilder();// 实例化数组
        int rows = 0;
        for (Method s : arr){// 遍历方法数组
            Parameter[] p = s.getParameters();// 获取参数
            for (Parameter pp : p){// 遍历参数  拼接字符串
                sb.append(pp.getType()).append(" ").append(pp.getName()).append(",");
            }
            // 参数最后一位 不需要,
            if (sb.length()>0) sb.deleteCharAt(sb.length()-1);

            // 输出
            System.out.printf("%d.String.%s(%s);%n",++rows,s.getName(),sb);
            // 清空字符串
            sb.delete(0,sb.length());
        }
    }

第三种

    public static void main(String[] args) {
        try {
            // 动态加载xx类的运行对象
            Class a = Class.forName("java.lang.String");
            // 获取成员方法的集合
            Method[] m = a.getDeclaredMethods();
            // 遍历成员方法的集合
            for (Method mm : m){
                // 打印权限修饰符、
                System.out.print(Modifier.toString(mm.getModifiers()));
                // 打印返回值类型名称
                System.out.print(" "+mm.getReturnType().getName()+" ");
                // 打印方法名称
                System.out.println(mm.getName()+"();");
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

标签:反射,String,System,Class,println,out,class,Reflection
From: https://www.cnblogs.com/xhlin/p/16776873.html

相关文章

  • 22、面向对象(反射)
    22.1、反射介绍:1、什么是反射:(1)反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机......
  • 反射
    标小红旗的重要!!!反射牛逼在:不修改源码的情况下,来控制程序,是设计模式里面最重要的开闭原则,也是框架的灵魂笔记链接https://blog.csdn.net/weixin_46594796/article/det......
  • 利用反射导出简单pdf报表
    leader给了导出pdf的需求,给了我示例代码,但我发现是硬编码的形式极大的影响了开发的效率。然后我思考了一下,它就是将实体对象的属性按顺序赋值,那我为何不用反射获取所有属......
  • java反射——设计框架的灵魂
    目录​​一、什么是反射(机制)​​​​二、反射的好处​​​​三、获取Class类对象的方式​​​​四、Class类的实例化对象具有的功能​​​​反射的应用​​​​1、写一个"框......
  • 通过反射的内省机制获取URL地址中出入的参数,并封装到对应的实体类中
    本例需要添加的依赖:<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope>......
  • 注解和反射
    注解注解入门Annotation是从JDK5.0开始引入的新技术Annotation的作用:不是程序本身,可以对程序作出解释(这一点和注释没有什么区别)可以被其他程序(比如:编译器)读取An......
  • 大白话说Java反射:入门、使用、原理
    反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释。一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例化,......
  • Java反射详解,学以致用,实战案例(AOP修改参数、Mybatis拦截器实现自动填充)
    持续创作,加速成长!这是我参与「掘金日新计划·10月更文挑战」的第1天,点击查看活动详情作为Java开发者,你认为反射这个知识点重要程度,在你心里是什么样的呢?以前我也只觉......
  • java注解与反射--3
    java注解与反射--3类的加载与ClassLoaderjava内存堆存放new的对象和数组可以被所有的线程共享,不会存放别的对象引用栈存放基本变量类型引用对象的变量方法......
  • go 反射
             ......