目录
注解(Annotation)
注解作用
- 注解可以被其他程序(比如编译器)读取
- 可以加在类,方法等上面,添加额外信息
- 可以通过反射机制实现对元数据的访问
元注解:负责注解其他注解
- @Target
- @Retention
- @Documented
- @Inherited
- @Repeatble
@Repeatble:一般一个地方不能有相同类型的注解,加了这个注解后就可以了
//自定义注解
//Target 表示我们的注解可以用在哪些地方
//ElementType.METHOD:可以作用在方法上
//ElementType.TYPE:可以作用在类上
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//Retention:注解的生命周期,一般都写runtime
//runtime>class>sources
@Retention(value = RetentionPolicy.RUNTIME)
//Documented:是否将我们的注解生成在javadoc中
@Documented
//Inherited 子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
//注解参数:参数类型 + 参数名()
//如果没有default ""则必须要有值
String value() default "" ;
}
反射(Reflection)
动态语言:它是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。
Java是一门准动态语言,是依靠反射机制实现的
获得Class对象
package com.lys.reflection;
//反射
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
//父类引用子类对象,对象是子类
Person person = new Student();
//通过反射获取类的Class对象
//方式一:通过对象获得
Class c1 = person.getClass();
System.out.println(c1.hashCode());
//方式二:forname获得
Class c2 = Class.forName("com.lys.reflection.Student");
System.out.println(c2.hashCode());
//方式三:通过类名.class获得
Class c3 = Student.class;
System.out.println(c3.hashCode());
//方式四:基本内置类型的包装都有一个Type属性
Class c4 = Integer.TYPE;
System.out.println(c4);
//获得父类型
Class c5 = c1.getSuperClass();
System.out.println(c5);
//一个类在内存中只有一个Class对象
//一个类被加载后,类的整个结构都会被封装在Class对象中
}
}
获取类运行时结构
java内存结构
类加载过程
加载:将字节码文件加载到内存,并把静态数据转换成方法区运行时的数据结构,且生成一个代表这个类的Class对象。
链接:将java类的二进制代码合并到jvm运行状态的过程
- 验证:确保符合jvm规范,不存在其他安全问题
- 准备:在方法区中,为静态变量分配内存,并设置初始值
- 解析:虚拟机常量池中的符号引用转换为直接引用(地址)
初始化:
- 执行<clinit()>方法,对代码块合并排序进行初始化操作。
- 若父类未初始化,则先初始化父类
- jvm会保证<clinit()>方法在多线程环境中被正确加锁和同步
类初始化
类加载器
版权声明:本文为weixin_50968698原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。