栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA 反射

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA 反射

注解与反射
  • 注解
    • 一、内置注解
    • 二、元注解
    • 三、自定义注解
  • 反射
    • 一、Java反射机制概述
    • 二、理解Class类并获取Class实例
      • 2.1 获取Class类的方法:
      • 2.2 哪些类型可以有Class对象
      • 2.3 类加载内存分析
    • 三、类的加载与ClassLoader
    • 四、创建运行时类的对象
    • 五、调用运行时类的指定结构
    • 六、反射操作注解

注解

Annotation是从JDK5.0开始引入的新技术

一、内置注解
@Override	//重写方法
@Deprecated	//废弃
@SuppressWarnings("all")	//镇压警告
二、元注解

元注解的作用就是负责注解其他注解,java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明(可以在java.lang.annotation包找到)

//表示注解可以用在什么地方
@Target(value = ElementType.METHOD)

//表示注解在什么时候还有效
@Retention(value = RetentionPolicy.RUNTIME)	//RUNTIME > CLASS > SOURCE

//表示是否将我们的注解生成在javadoc
@documented		

//表示子类可以继承父类的注解
@Inherited 
三、自定义注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
	//注解的参数:参数类型 + 参数名 ();
	String name() default "";
	int age();
	int id default -1;
}
反射 一、Java反射机制概述 二、理解Class类并获取Class实例 2.1 获取Class类的方法:
  1. 已知具体的类,通过类的class属性获取(最安全可靠,程序性能高)

    Class clazz = Person.class;

  2. 已知某个类的实例,调用该实例的getClass()方法获取Class对象

    Class clazz = person.getClass();

  3. 已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取(可能抛出异常ClassNotFoundException)

    Class clazz = Class.forName(“demo01.Student”);

  4. 内置基本数据类型可以直接用类名.Type

  5. ClassLoader

2.2 哪些类型可以有Class对象
  1. class:外部类,成员(成员内部类、静态内部类),局部内部类,匿名内部类
  2. interface:接口
  3. []:数组
  4. enum:枚举
  5. annotation:注解@interface
  6. primitive type :基本数据类型
  7. void
        Class c1 = Object.class;        //类
        Class c2 = Comparable.class;    //接口
        Class c3 = String[].class;      //一维数组
        Class c4 = int[][].class;       //二维数组
        Class c5 = Override.class;      //注解
        Class c6 = ElementType.class;   //美剧
        Class c7 = Integer.class;       //基本数据类型
        Class c8 = void.class;          //void
        Class c9 = Class.class;         //Class
2.3 类加载内存分析

​ 类的加载过程

(1)加载:将类的class文件读入内存,类的结构放在方法区如上图Pet

(2)链接:在堆区为其创建一个java.lang.Class对象

(3)初始化:

类构造器方法() {
	将静态代码合并
}

(4)当new对象时,先找到class对象,通过其去找类的结构

三、类的加载与ClassLoader

类加载器的作用:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法去的运行时数据结构,然后在堆中生成一个代表这个类的Java.lang.Class对象,作为方法去中数据的访问入口。

类缓存:标准的javaSE类加载器可以按要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过JVM垃圾回收机制可以回收这些Class对象。

类加载器作用是用来把类(Class)装载进内存的。JVM规范定义了如下类型的类加载器:

		//获取系统类的加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        //获取系统类加载器的父类加载器-->扩展类加载器
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);

        //获取扩展类加载器的父类加载器-->根加载器(c/c++), 无法直接获取
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);

        //测试当前类是哪个加载器加载的
        try {
            ClassLoader classLoader = Class.forName("com.kuang.onlytest.ClassLoaderTest").getClassLoader();
            System.out.println(classLoader);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

双亲委派机制

四、创建运行时类的对象

获取运行时类的完整结构(不常用)

		Class c1 = Class.forName("com.kuang.onlytest.User");

		//获得类的名字
        System.out.println(c1.getName());
        System.out.println(c1.getSimpleName());

		//获得类的属性	异常:NoSuchFieldException
        Field[] fields = c1.getFields();//只能获得public属性,会抛异常
        Field[] fields2 = c1.getDeclaredFields();//找到所有属性

		//获得指定属性
		Field f = c1.getField("name");
		
		//获得类的方法	异常:NoSuchMethodException
        Method[] methods = c1.getMethods();     //除了本类以及父类的public方法
        Method[] methods2 = c1.getDeclaredMethods();      //获得本类的所有方法
		
		//获得指定方法
		Method m = c1.getMethod("getName");

		//获得类的构造器
		Constructor[] constructors = c1.getConstructors();
		Constructor[] constructors = c1.getDeclaredConstructors();

		//获得指定构造器
		Constructor declaredConstructor = c1.getDeclaredConstructor(Stirng.class);

五、调用运行时类的指定结构

Class对象的作用

  1. 创建类的对象

    		//获得Class对象
            Class c1 = Class.forName("com.kuang.onlytest.User");
    
            //通过newInstance创建对象(该方法已被弃用)
            User u = (User)c1.newInstance();
    
    		//通过构造器创建对象
            Constructor c = c1.getDeclaredConstructor(String.class);
            User user = (User)c.newInstance("zou");
            
    
  2. 通过反射调用普通方法

    		//通过反射调用普通方法,获取方法 -> 激活方法invoke(对象, "方法的参数")
            User user3 = (User) c1.newInstance();
            Method setName = c1.getDeclaredMethod("setName", String.class);
            setName.invoke(user3, "zou");
    
    
  3. 通过反射操作属性

    		//通过反射操作属性,如果是private,需要关闭权限检测
            Field name = c1.getDeclaredField("name");
            name.setAccessible(true);
            name.set(user3, "hah");
            System.out.println(user3);
    
六、反射操作注解
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/344983.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号