注解和反射笔记
java.Annotation包
Annotation是从JDK5.0开始引入的新技术
Annotation的作用:
Annotation的格式
Annotation在哪里使用?
@Override:定义在java.lang.Override中,此注解只适合用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明
@Deprecated:定义在java.lang.Deprecated中,此注解可以用于修辞方法,属性,类,表示不鼓励程序员使用这样的元素,通常是因为他们很危险或者存在更好的选择
@SuppressWarnings:定义在java.lang.SuppressWarning中,用来抑制编译时的警告信息。
使用@interface
自定义注解时,自动继承了java.lang.anntation.Anntation接口
分析:
/**
* @author zhang
* @date 2020/6/10 19:05
*/
public class Demo3 {
@MyAnnotation2(name = "张三",schools = {"黑龙江八一农垦大学"})
public void test(){}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
//注解的参数
String name() default "";
int age() default 0;
int id() default 1;
String[] schools() default {"清华大学"};
}
Class c = Class.forName("java.lang.String")
Java反射的优缺点
优点:可以实现动态创建对象和编译,体现出很大的灵活性
缺点:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么兵器它满足我们的需求。这类操作总是慢于直接执行相同的操作。
Class类
对象照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE都为其保留了一个不变的Class类型的对象。一个Class对象包含了特定的某个结构(class/interface/enum/annotation/primitive type/void[])的有关信息。
Class的常用方法
方法名 | 功能说明 |
---|---|
static ClassforName(String name) | 返回指定类名name的Class对象 |
Object newInstance() | 调用缺省构造函数,返回一个Class对象的实例 |
getName() | 返回此Class对象表示的实体(类、接口、数组类或void)的名称 |
Class getSuperClass | 返回当前Class对象的父类Class对象 |
Class[] getinterfaces | 返回当前Class对象的接口 |
ClassLoader getClassLoader | 返回该类的类加载器 |
Constructor[] getConstructors() | 返回一个包含某些Constructor对象的数组 |
Method getMethod(String name,Class… T) | 返回一个Method对象,此对象的参数类型为paramType |
Field[] getDeclaredFields() | 返回Field对象的一个数组 |
类的加载过程
当程序主动使用某个类时,如果该类未被加载到内存中,则系统会通过如下三个步骤来对该类进行初始化。
()
方法的过程。类构造器()
方法由编译器自动收集类中所有变量的赋值动作和静态代码块中的语句合并产生的。(类构造器时构造类信息的,不是构造该类对象的构造器)()
方法在多线程环境中被正确加锁和同步。什么时候会发生类的初始化?
类加载器的作用:将class文件的字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口,
类缓存:标准的javaSE类可以按照要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过JVM垃圾回收机制可以回收这些Class对象
通过反射获取运行时类的完整结构
Field、Method、Constructor、Superclass、Interface、Annotation
package reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author zhang
* @date 2020/6/12 15:59
*/
public class Demo6 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
Class<?> c1 = Class.forName("reflect.User");
//获得类的名字
System.out.println(c1.getName());
System.out.println(c1.getSimpleName());
//获得类的属性
Field[] fields = c1.getFields();//只能获得public修饰的
for (Field field : fields) {
System.out.println(field);
}
Field[] fields1 = c1.getDeclaredFields();
for (Field field : fields1) {
System.out.println(field);
}
//获得类的方法
Method[] methods = c1.getMethods();//获得本类机器父类的全部public方法
for (Method method : methods) {
System.out.println(method);
}
//获得构造器
Constructor<?>[] constructors = c1.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
//获得指定的构造器
Constructor<?> constructor = c1.getConstructor(String.class,int.class,int.class);
System.out.println(constructor);
}
}
创建类的对象:调用Class对象的newInstance()方法
调用指定的方法
通过反射,调用类中的方法,通过Method类完成。
Object invoke(Object obj,Object...args)