注解和反射

注解和反射

1.反射的三种方式

  1. 通过对象获得
    Student student=new Student();
    Class class1=student.getClass();
    
  2. 通过forName获得
    Class class2=Class.forName("com.kuang.reflection.Student");
    
  3. 通过类名.class获得
    Class class3=Student.class;
    

2.Java内存分析

2.1Java内存

  • 存放new的对象和数组,可以被所有线程共享
  • 存放基本变量类型(会包含这个基本类型的具体数值)
      引用对象的变量(会存放这个引用在堆里面的具体地址)
  • 方法区 可以被所有线程共享,包含所有的class和static变量

3.内加载器

测试类是哪个加载器加载的

ClassLoader classLoader=Class.forName("com.kuang.reflection.Student").getClassLoader();

4.获取类的运行时结构

   Class class2=Class.forName("com.kuang.reflection.Student");
   class2.getName();//**获取全类名**
   class2.getSimpleName();//**获取简单类名**
   Field[] fields=class2.getFields();//**获取类的所有public属性**
   Field[] fields=class2.getDeclaredFields();//**获取所有本类私有的属性**
   Field field=class2.getDeclaredFields("name");//**获取指定属性值**
   Method[] methods=class2.getMethods();//**获取本类及父类的所有public的方法**
   Method[] methods=class2.getDeclaredMethods();//**获取所有本类所有的方法**
   Method method=class2.getMethod("setName","String.class");//**获取指定方法**
   Constructor[] constructors=class2.getConstructor();//**获取本类的所有public构造器方法**
   Constructor[] constructors=class2.getDeclaredConstructor();//**获取所有本类所有构造器方法**
   Constructor constructor=class2.getDeclaredConstructor("String.class","int.class","int.class"); constructor=class2.getDeclaredConstructor("String.class","int.class","int.class");//**获取所有本类所有构造器方法**

5.动态创建对象,通过反射

通过反射获取到class对象,调用getMethod()方法获取到Method对象,调用Method对象的invoke方法可以调用方法,需要指定方法参数

若原方法声明为private,则需要在调用此incoke()方法钱,显式调用方法对象的setAccessible(true)方法。

setAccessible

  • Method、Field、Constructor对象都有setAccessible()方法
  • 作用是启动和禁用访问安全检查的开关
  • 参数值为true则指示反射的对象在使用时应该取消Java语言访问检查
      如果代码频繁被调用,请设置为true
      使得原本无法访问的私有成员可以访问
    Class class2=Class.forName("com.kuang.reflection.Student");
    //创建一个对象
    Student student=(Student) class2.newInstance();
    
    //通过构造器创建对象
    Constructor constructor=class2.getDeclaredConstructor("String.class","int.class","int.class");
    Student student2=(Student) constructor.newInstance("老王",001,18);
    
    //通过反射获取一个方法
    Method setName=class2.getMethod("setName","String.class");
    setName.invoke(student,"狂神")
    
    //通过反射操作属性
    Field name=class2.getDeclaredFields("name");
    name.setAccessile(true);//不能直接操作私有属性,需要关闭程序的安全检测,会降低程序效率
    name.set(student,"狂神2");

6.通过反射获取泛型

  • Java采用泛型擦除的机制来引入泛型 , Java中的泛型仅仅是给编译器javac使用的,确保数据的安全性
    和免去强制类型转换问题 , 但是 , 一旦编译完成 , 所有和泛型有关的类型全部擦除

  • 为了通过反射操作这些类型 , Java新增了 ParameterizedType , GenericArrayType ,
    TypeVariable 和 WildcardType 几种类型来代表不能被归一到Class类中的类型但是又和原始类型齐名的类型.

  • ParameterizedType : 表示一种参数化类型,比如Collection

  • GenericArrayType : 表示一种元素类型是参数化类型或者类型变量的数组类型

public class test11 {
    public void test01(Map<String,Student> map,List<Student> list){
        System.out.println("test01");
    }

    public Map<String,Student> test02(){
        System.out.println("test02");
         return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method method = test11.class.getMethod("test01", Map.class, List.class);

        Type[] genericParameterTypes = method.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println("#"+genericParameterType);
        if(genericParameterType instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }
    }

        method=test11.class.getMethod("test02", null);
        Type genericReturnType = method.getGenericReturnType();
        if(genericReturnType instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }

    }
}

posted @   KxWanna  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示