一、类加载
类加载是指将类的class文件读入内存,并为之创建一个java.lang.Class对象。系统可以在第一次使用某个类时加载该类,也可以采用预加载机制来加载某个类。
1、Class类
java.lang.Class类封装了一个对象和接口运行时的状态,当加载类时Class类型的对象将自动创建。Class类没有公共构造方法,其对象是JVM在加载类时通过调用
类加载器中的defineClass()方法自动构造,因此不能显示地实例化一个Class对象。
Class类的常用方法(记得填坑)
每个类被加载之后,系统都会为该类生成一个对应的Class对象,通过Class对象就可以访问到JVM中该类的信息。一旦类被载入JVM中,同一个类将不会被再次载入,
被载入JVM的类都有一个唯一表示,该表示是该类的全限定类名。
在Java程序中获取Class对象有如下三种方式:
1 //1、使用Class.forName()方法 2 Class strClass = Class.forName("java.lang.String"); 3 //2、使用类的class属性 4 Class<Float> fclass = Float.class; 5 //3、使用实例对象的getClass()方法 6 Date nowTime = new Date(); 7 Class dateClass = nowTime.getClass();
2、类加载步骤
类的加载有三个步骤:加载、连接、初始化。
类的加载是由类加载器完成,类加载器由JVM提供;除此之外,开发者可以通过继承ClassLoader类来创建自己的类加载器。通过使用不同的类加载器,可以从
不同来源加载类的二进制数据。
类的连接是指将类的二进制数据合并到JRE中。
类的初始化是指对类变量进行初始化。有以下几个步骤:
(1)如果类没有被加载和连接,则程序先加载并连接该类
(2)如果类的直接父类未被初始化,则先初始化其直接父类
(3)如果类中有初始化语句,则系统直接执行初始化语句
因此,当程序使用任何一个类时,JVM会保证该类及其所有祖先类都会被初始化。
3、类加载器
类加载器负责将磁盘或网络上的.class文件加载到内存中,并为之生成对应的java.lang.Class对象。
4、ClassLoader类
java.lang.ClassLoader是一个抽象类,通过继承ClassLoader类来实现自定义的用户类加载器,以扩展JVM动态加载类的方式。
ClassLoader类中包含了大量的protected方法,都可以在子类中被重写。(有待理解完善)
二、反射
在程序运行时获取对象的真实信息有以下两种做法:
**在知道对象的具体类型的情况下,可以先使用instanceof 运算符进行判断,再利用类型强制转换将其转换成运行时的类型变量
**在无法预知该对象属于哪些类的情况下,必须通过反射来发现该对象和类的真实信息
反射机制允许程序在运行时借助Reflection API取得任何类的内部信息,并能直接操作对象的内部属性及方法。
Java反射机制主要提供了以下功能:
*在运行时判断任意一个对象所属的类
*在运行时构造任意一个类的对象
*在运行时获取任意一个类所具有的成员变量和方法
*在运行时调用任意一个对象的方法
*生成动态代理
1、Executable抽象类
该抽象类代表可执行的类成员。Executable抽象类派生了Constructor和Method两个子类。Executable抽象类提供了大量方法来获取参数、
修饰符或注解等信息。
2、Constructor类
Constructor类用于表示类的构造方法,通过调用Class对象的getConstructors( )方法可以获取当前类的构造方法的集合。
3、Method类
Method类用于封装方法的信息,调用Class对象的getMethods( )或getMethod( )可以获取当前类的所有方法或指定方法。
4、Field类
Field类用于封装属性的信息,调用Class对象的getField( )或getFields( )方法可以获取当前类的所有属性或指定属性。
5、Parameter类
Parameter类也是Java 8 新增的API,每个Parameter对象代表方法的一个参数。
三、枚举
在开发过程中,经常遇到一个类的实例对象是有限而且固定的情况。
定义枚举类使用enum关键字。枚举类是一种特殊的类,与普通类有如下区别:
**枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是继承Object类,因此枚举类不能显式继承其他父类。
**使用enum定义非抽象的枚举类时默认会使用final修饰,因此枚举类不能派生子类。
**枚举类的构造方法只能使用private访问修饰符
**枚举类的所有实例必须在枚举类的类体第一行显式列出,否则该枚举类永远不能产生实例。列出的枚举实例默认使用public static final进行修饰。
1、定义枚举类
语法格式:
[ 修饰符 ] enum 枚举类名{
//第一行列举枚举实例
}
枚举一旦被定义,就可以直接使用该类型的枚举实例。所有枚举类型都会包括两个预定义方法:values( ) 和 valuesOf( )
方法 | 功能描述 |
public static enumtype []values() | 返回一个枚举类型的数组,包含该枚举类的所有实例值 |
public static enumtype valueOf(String str) | 返回指定名称的枚举实例值 |
语法:枚举类.实例
2、包含属性和方法的枚举类
枚举类也是一种类,具有与其他类几乎相同的特性,因此可以定义枚举的属性、方法以及构造方法。但是,枚举类的构造方法只是在构造枚举实例值时
被调用。每一个枚举实例值都是枚举类的一个对象,因此创建每个枚举实例时都需要调用该构造方法。
1 public enum Season { 2 //第一行列出4个枚举实例:春夏秋冬 3 SPRING("春"),SUMMER("夏"),FALL("秋"),WINTER("冬"); 4 //定义一个属性 5 private String name; 6 //构造方法 7 Season(String name){ 8 this.name = name; 9 } 10 //方法 11 public String toString(){ 12 return this.name; 13 } 14 15 }
3、Enum类
所有枚举类都继承自java.lang.Enum,该类定义了枚举类公用的方法。这个类实现了java.lang.Serializable和java.lang.Comparable两个接口
四、注解
注解Annotation是告知编译器要做什么事情的说明,在程序中可以对任何元素进行注解,包括:Java包、类、构造方法、域、方法、参数、属性等。
APT注解处理工具负责提取注解中包含的元数据,并会根据这些元数据增加额外功能。
注解中元数据的作用:编写文档、代码分析、编译检查
1、基本注解
@Override:用于限定重写父类的方法,使用该注解修饰的方法必须重写父类中的方法,否则会发生编译错误
@Deprecated:用于标示某个元素已过时,当程序使用已过时的类、方法等,编译器会给出警告
@SuppressWarnings:用于抑制编译警告的发布,允许开发人员取消显式指定的编译器警告;
@SafeVarargs:在Java 7中新增,用于抑制“堆污染”警告
@FunctionalInterface:在Java 8中新增,用于指定某个接口必须是函数式接口
2、定义注解
语法格式:
[ 修饰符 ] @interface 注解名{
。。。
}
自定义注解是通过@interface声明,注解的成员由未实现的方法组成,方法只有声明没有方法体,注解中的成员将在使用时进行实现
在定义注解时,可以使用default语句为注解成员指定默认值。语法:类型成员( ) default 值;
1 @Retention(RetentionPolicy.RUNTIME) 2 public @interface MyAnno { 3 String comment(); 4 int order(); 5 }
3、使用注解
注解大多是为其他工具提供运行信息或决策依据而设计的,任何Java程序都可以通过使用反射机制来查询实例的信息。
在java.lang.reflect中有一个AnnotatedElement接口,用于在反射过程中获取注解信息,并为注解相关操作提供支持。
方法 | 功能描述 |
Annotation getAnnotation(Class annotype) | 返回调用对象的注解 |
Annotation getAnnotations() | 返回调用对象的所有注解 |
Annotation getDeclareedAnnotations() | 返回调用对象的所有非继承注解 |
Boolean isAnnotationPresent(Class annotype) | 判断与调用对象关联的注解是由annotype指定的 |
1 //使用自定义的@MyAnno注解修饰类 2 @MyAnno(comment = "类注解", order = 1) 3 class MyClass{ 4 //使用自定义的@MyAnno注解修饰方法 5 @MyAnno(comment = "方法注解", order = 2) 6 public void method(){ 7 8 } 9 } 10 public class AnnoDemo { 11 public static void main(String[] args) throws Exception { 12 //获取MyClass类注解 13 MyAnno anno = MyClass.class.getAnnotation(MyAnno.class); 14 //输出类注解信息 15 System.out.println(anno.comment()+"序号:"+anno.order()); 16 //获取MyClass类的method方法 17 Method mth = MyClass.class.getMethod("method"); 18 //获取该方法的注解 19 MyAnno anno1 = mth.getAnnotation(MyAnno.class); 20 //输出 21 System.out.println(anno1.comment()+"序号:"+anno1.order()); 22 } 23 }
4、元注解
元注解的作用就是负责注解其他注解。
@Retention:指定其所修饰的注解的保留周期
@Document:该注解是一个标记注解,用于指示一个注解将被文档化
@Target:用来限制注解的使用范围
@Inherited:该注解使父类的注解能被子类继承
@Repeatable:该注解是Java 8新增的注解,用于开发重复注解
类型注解(Type Annotation):该注解是Java 8 新增的注解,可以用在任何用到类型的地方。
来源:https://www.cnblogs.com/kadaj174/p/10984571.html