复学day10
注解/Annotation
Annotation是从JDK5.0开始引入的技术。
Annotation的作用:
1、不是程序本身,但可以对程序做出解释(这一点和注释类似)。
2、可以被其他程序(比如:编译器等)读取。
Annotation的格式:
注解是以“@注释名”在代码中存在的(@override),可以添加一些参数值,例如:@SuppressWarnings(value="unchecked")。
Annotation可以附加在package,class,method,field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问。
内置注解
@Override:定义在java.longOverride中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法。
@Deprecated:定义在java.lang.Deprecated中,此注释可以用于修辞方法,属性,类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择,但是可以使用。
@SuppressWarnings:定义在Java.lang.SuppressWarnings中,用来抑制编译时的警告信息。
与前两个注释有所不同,这个注释需要添加添加一个参数才能正确使用,这些参数倒是已经定义好了的,如:@SuppressWarnings("all")、@SuppressWarnings("unchecked")、@SuppressWarnings(value={"unchecked","deprecation"})等等......
元注解
元注解的作用就是负责注解其他注解,Java定义了4个标准的meta-annotation类型,他们对其他annotation类型提供说明的作用。
这4个标准的元注解是:@Target、@Retention、@Documented、@Inherited。
@Target:用于描述注解的使用范围(即:被描述的注解用在什么地方)
@Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(SOURCE<CLASS<RUNTIME,有效范围,source表示读取源码时有效,class表示读取字节码文件时有效,runtime表示运行便有效)
@Docunment:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
自定义注解
关键字@interface 自定义注解,自动继承Java.lang.annotation.Annotation接口。
@interface用来声明一个注解,格式:public @interface 注解名{定义内容}
public class Test{
@MyAnnotation(age = 18) //注解中设有参数,如果并没有通过default设置默认值,则必须输入参数,负责会报错
public void test(){}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
//注解的参数:参数类型+参数名()
String name() default "";//必须要有括号
int age();
}
}
注解的学习目前偏抽象,实际用途在后面学习框架时会清晰很多。
反射/Reflection
这里首先引出动态语言和静态语言这两个概念。
动态语言指的是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码引进,已有的函数可以被删除或是其他结构上的变化。(常见的现象:游戏外挂,在游戏运行时修改系统参数)常见的动态语言:Object、C#、JavaScript、PHP、Python等。
静态语言与动态语言相对应,运行时结构不可变的语言。如Java、C、C++。
Java不是动态语言,但是Java可以称之为“准动态语言”。即Java有一定的动态性,这一特性便是由反射机制带来的。
Reflection是java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并且能直接操作任意对象的内部属性及方法,
//Class 反射的核心类
Class c = Class.forName("java.lang.String")
加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。
常规:引入需要的“包类”名称 ---- 通过new实例化 ---- 取得实例化对象
反射:实例化对象 ---- getClass()方法 ---- 得到完整的”包类“名称
public class Test{
public static void main(String[] args) throw ClassNotFoundException{
//通过反射获取类的class对象
Class c1 = Class.forName("com.reflection.User");
c1.//c1为Class对象,此时可以获得User类中的方法getMethod()、注解getAnnotation等
//一个类有且仅有一个Class对象,下面c1、c2、c3的哈希值相等
Class c2 = Class.forName("com.reflection.User");
Class c3 = Class.forName("com.reflection.User");
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3hashCode());
}
class User{
private String name;
private int age;
public User(){}
public User(String name, int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
}
Class类
对于每个类而言,Jre都为其保留一个不变的Class类型的对象,由此这个Class对象值得挪列出来单独说一说。
特点:
1、Class本身也是一个类,是Reflection的根源
2、Class对象只能由系统建立对象
3、一个加载的类在JVM中只会有一个Class实例
4、一个Class对象对应的是一个加载到JVM中的一个.class文件
5、每个类的实例都会记得自己是由哪个Class实例所生成
6、通过Class可以完整地得到一个类中的所有被加载的结构

浙公网安备 33010602011771号