------- android培训、java培训、期待与您交流! ----------
一、注解
1.注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,就等于没有这种标记。以后,javac编译器,开发工具和其他工具可以用反射来了解你的类和各种元素上有无何种标记。看你有什么标记,就去干相应的事。标记可以加载包、类、字段、方法、方法的参数以及局部变量上。
2.三个基本Annotation
(1).@Override:限定重写父类方法。可以强制子类必须覆盖父类中的方法。且只能用于修饰方法。
(2).@Deprecated:表示某个程序(类、方法)已过时,当其他程序使用已过时的类、方法时,编译器将会给出警告。
(3).@SuppressWarnings:表示被Annotation标识的程序元素取消显示指定的编译器警告。
3.自定义Annotation
(1).形式:public @interface Test{} 可用于修饰类、方法、变量、接口等;
(2).Annotation还可以带成员变量,成员变量在Annotation中以无参数方法的形式来声明。如:
public @interface MyTag{
String name();
int age(); //成员变量以方法的形式来定义
}
(3).定义成员变量后,使用时应该为该成员变量赋值。如@MyTag(name="xx",age=6) 也可以为该成员变量指定初始值,指定时用"default"关键字 如:
public @interface MyTag{
String name() default "xin";
int age() default 22; //成员变量以方法的形式来定义
}
4.分类:
(1).标记Annotation:一个没有定义成员变量的Annotation类型;
(2).元数据Annotation:那些包含成员变量的Annotation,可接受更多元数据;
(1).@Override:限定重写父类方法。可以强制子类必须覆盖父类中的方法。且只能用于修饰方法。
(2).@Deprecated:表示某个程序(类、方法)已过时,当其他程序使用已过时的类、方法时,编译器将会给出警告。
(3).@SuppressWarnings:表示被Annotation标识的程序元素取消显示指定的编译器警告。
3.自定义Annotation
(1).形式:public @interface Test{} 可用于修饰类、方法、变量、接口等;
(2).Annotation还可以带成员变量,成员变量在Annotation中以无参数方法的形式来声明。如:
public @interface MyTag{
String name();
int age(); //成员变量以方法的形式来定义
}
(3).定义成员变量后,使用时应该为该成员变量赋值。如@MyTag(name="xx",age=6) 也可以为该成员变量指定初始值,指定时用"default"关键字 如:
public @interface MyTag{
String name() default "xin";
int age() default 22; //成员变量以方法的形式来定义
}
(4).当注解中的属性名为value时,在对其赋值时可以不指定属性的名称而直接写上属性的值即可;除了value以外的其他值都需要使用
name=value这种赋值方式,即明确指定给谁赋值;
(5).没有元素的注解成为标记注解;
(6).为注解增加属性
a.数组类型的属性
如果数组属性中只有一个元素,这时候属性值部分可以省略大括号。
b.枚举类型的属性
c.注解类型的属性
4.分类:
(1).标记Annotation:一个没有定义成员变量的Annotation类型;
(2).元数据Annotation:那些包含成员变量的Annotation,可接受更多元数据;
5.Class、Constructor、Field、Method、Package等类别,都实现了
AnnotatedElement接口;
6.
(1).当使用@interface关键字定义一个注解时,该注解隐含的继承了java.lang.annotation.Annotation接口;
(2).如果我们定义了一个接口,并且让该接口继承自Annotation,那么我们所定义的接口依然还是接口而不是注解;
(3).Annotation本身是接口而不是注解;
7.
元注解:
(1).@Target:表示该注解可以用于什么地方;ElementType参数包括:
CONSTRUCTOR(构造器的声明)、
FIELD:域声明、:
LOCAL_VARIABLE:局部变量声明、
METHOD:方法声明、
PACKAGE:包声明、
PARAMETER:参数声明、
TYPE:类、接口(包括注解类型)或enum声明;
(2).Retention:表示需要在什么级别保存该注解信息;RetentionPolicy参数包括:
SOURCE:注解将被编译器丢弃;
CLASS:注解在class文件中可用,但会被VM丢弃;
RUNTIME:VM将在运行期也保存注解,因此可以通过反射机制读取注解信息;
8.
注解元素默认值限制:
(1).元素不能有不确定的值;也就是说元素要么具有默认值,要么在使用注解时提供元素的值;
(2).对于非基本类型的元素,无论是在源代码中声明时,或是在注解接口中定义默认值时,都不能以null作为其值。这样使得处理器很难表现一个元素的存在或缺失的状态,为了解决这个问题,我们只能自己定义一些特殊的值,例如空字符创或负数,一次表示某个元素不存在;
9.注解不支持继承
二、类加载器
1.概念
(1).Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类加载器负责加载特定位置的类:BootStrap、ExtClassLoader、AppClassLoader
(2).类加载器也是java类,因为其他是java类的类加载器本身也要被加载,所以必须要有一个类加载器不是java类,它就是BootStrap,一个C++编写的二进制文件。
(3).Java虚拟机中所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象时,需要为其制定一个父级类装载器对象或者采用系统类装载器为其父级类加载
(4).三个类加载器的继承关系为:AppClassLoader(CLASSPATH指定的所有jar或目录) —>ExtClassLoader(JRE/lib/ext/*.jar) ——> BootStrap(JRE/lib/rt.jar)。
2.类加载器的委托机制
(1).java虚拟机加载一个类的过程:
a.首先当前线程的类加载器去加载线程中的第一个类。
b.如果类A中引用了类B,java虚拟机将使用加载类A的类装载器来加载类B。
c.还可以直接调用ClassLoader loadClass()方法来指定某个类加载器去加载某个类。
(2).每个类加载器加载类时,又先委托给其上级类加载器。
a.当所有祖宗类加载器没有加载到类,回到发起者类加载器,如果还加载不了,就抛出ClassNotFoundException,不是再去找发起者类加载器的儿子。
3.编写自己的类加载器
(1).自定义的类加载器必须继承ClassLoader。
(2).loadClass方法和findClass方法。
(3).defineClass方法。