复学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可以完整地得到一个类中的所有被加载的结构

img

posted @ 2020-11-20 18:27  何安生  阅读(114)  评论(0)    收藏  举报