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 fuhua277@163.com
 * @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 fuhua277@163.com
 * @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 fuhua277@163.com
 * @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);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值