java1.3 注解和反射

本文详细介绍了Java中的注解和反射机制。注解包括内置注解如@Override、@Deprecated、@SuppressWarnings及其元注解,同时讲解了如何自定义注解。反射部分探讨了Class类、类加载与ClassLoader的工作原理,以及如何通过反射获取和操作类的结构,包括创建对象、调用方法和修改属性等。此外,还讨论了反射在动态编程中的优缺点。
摘要由CSDN通过智能技术生成

一.注解

java.Annotation

1.1 概述

作用:不是程序本身,对程序作出解释。可以被其他程序读取

格式:以 @注释名 在代码中存在,可以添加参数

1.2 内置注解

@Override

​ 说明:仅用于修饰方法,表示一个方法声明打算重写超类中的一个方法

@Deprecated

​ 说明:修饰 方法、属性、类,表示不建议使用(存在危险或有更好的选择)

@SuppressWarnings

​ 说明:用来抑制编译时的警告信息,不同的是该注解需要传参

  • @SuppressWarnings(“all”) //全部
  • @SuppressWarnings(“unchecked”) //未检查的
  • @SuppressWarnings(value={“unchecked”,“deprecation”})
1.3 元注解 (负责注解其他注解)

@Target

说明:用于描述注解的使用范围

例:@Target( value={ElementType.METHOD , ElementType.TYPE} ) //在方法和类中可用

@Retention

说明:注解级别 SOURCE < CLASS < RUNTIME

例:@Retention( Retentionpolicy.RUNTIME )

@Document(了解)

说明:该注解生成在 javadoc 中

@Inherited(了解)

说明:子类可继承父类中的该注解

1.4 自定义注解

使用 @interface 自定义注解

@Target( value={ElementType.METHOD} )
@Retention( Retentionpolicy.RUNTIME )
@interface MyAnnotation{
    String value() default "默认值";
}// value 为注解的 参数

二.反射

java.Reflection

2.1 概述
  • 实现java动态的关键
  • 允许程序在执行期借助 Reflection API 获取任何类的信息(并操作)

正常 引入“包类”名称 -> new实例化对象 -> 取得实例化对象

反射 实例化对象(包含类的完整信息) -> getClass方法 -> 得到“包类名称”

  • 优缺点
    • 优:实现了动态创建对象和编译,体现出java的灵活性
    • 缺:影响性能,不建议大量使用
2.2 Class类与Class实例

导包

java.lang.class 类

java.lang.reflect.Method 类的方法

java.lang.reflect.Field 类的成员变量

java.lang.reflect.Constructor 构造器

获取类的方法

// no1 通过对象获取(person是类的实例对象)
Class c1 = person.getClass();
// no2 forName输入包名获取
Class c2 = Class.forName("reflection.Student");
// no3 通过 类名.class 获取【效率最高】
Class<Student> c3 = Student.class;
// no4 获得类的父类
Class c4 = c1.getSuperclass();
2.3 类的加载与 ClassLoader

2.3.1 Java运行原理

加载:将class字节码加入内存,将静态数据换成方法区的运行时数据结构,生成类

链接:java代码合并到 JVM 运行状态中

初始化:执行类构造器() 方法

2.3.2 什么时候会发生类初始化

  • 主动引用
    • 当虚拟机启发,会初始化main方法所在类
    • new 一个类的对象
    • 初始化一个类,会先初始化其父类
    • 调用静态成员变量和静态方法
    • 对类进行反射调用
  • 被动引用
    • 通过子类引用父类静态变量,不会初始化子类
    • 数组定义类引用,不会触发此类初始化 // 类名[] arr= new 类名[10];
    • 引用常量,不会触发此类初始化

2.3.3 类加载器

getClassLoader() 获取类加载器

2.4 获取运行时类的完整结构
方法说明
Class.getName()获得包名
Class.getFields()获取所有public属性
Class.getDeclaredFields()获取所有属性
Class.getMethods()获得类方法及其继承的方法
Class.getDeclaredMethods()获得本类中所有方法
Class.getMethod(name,…p)获得指定方法(方法名,参数类型)
Class.getConstructors()获得构造器

* 注:获得多个属性或方法的返回值是数组

2.5 调用运行时类的指定结构

2.5.1 动态创建对象newInstance()

User user = new User();
Class aClass = user.getClass();
//创建对象--无参--User{name='null', age=0, Id=0}
User obj1 = (User)aClass.newInstance();
System.out.println(obj1.toString());
//创建对象--带参--User{name='张三', age=0, Id=3}
Constructor constr = aClass.getDeclaredConstructor(String.class, int.class);
User obj2 = (User)constr.newInstance("张三", 003);
System.out.println(obj2.toString());

**2.5.2 调用方法 **invoke(对象,参数)

Method setName = aClass.getDeclaredMethod("setName", String.class);
setName.invoke(obj1,"李四");//不带参时,参数列表输入null
System.out.println(obj1.getName());

2.5.3 操作属性

Field name = aClass.getDeclaredField("name");
name.set(obj1,"王五");
System.out.println(obj1.getName());

2.5.4 扩展

1.获取泛型:编译完成后,泛型有关的类型全部擦除 > 通过反射操作类型

2.获取注解: 利用注解和反射完成类和表结构的映射

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值