注解和反射
注解 Annotation
注释只能给人看,而注解不仅给人看,还可以给程序解释和读取
作用
- 和注释(comment)一样可以对程序做出解释
- 还可以被其他程序(比如编译器)读取
格式
- @注释名,可以添加一些参数
使用
- 可以在包、类、方法、文件等上面使用,相当于辅助信息,然后通过反射机制编程实现对这些元数据的访问
内置注解
注解均在java.lang包下
- @Override:重写父类方法的一种修饰注解,只适用于修饰方法
- @Deprecated:表式不鼓励程序员用这些元素的一种注解,通常是因为他很危险或者存在更好的选择。可以修饰方法,属性和类
- @SuppressWarning:用来抑制编译时的警告信息,也是可以放在方法,属性和类上
- 不同的是它需要参数,如all,unchecked等
//镇压全部警告
@SuppressWarnings("all")
public class Test01 {
@Override
public String toString() {
return super.toString();
}
@Deprecated
public void test(){
System.out.println("Deprecated");
}
public static void main(String[] args) {
Test01 test01 = new Test01();
test01.test();
}
}
元注解
用来注解其他注解,可以定义注解
-
Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型做说明
- @Target:描述注解使用的范围,可以用在什么地方
- @Retention:描述注解的生命周期,表示在什么级别保存注释信息
- (SOURCE(源码)<CLASS(编译后的.class)<RUNTIME(运行时))
-
- @Document:可用在javadoc中
- @Inherited:子类可以继承父类的注解
自定义注解
- @interface:用来定义一个注解
import java.lang.annotation.*;
public class Test02 {
//自定义的注解,有参数要写,也可以在下面设置默认值
@MyAnnotation()//(name = "yjj")
public void test(){
}
}
//定义一个注解
//value是一个参数,可以有多个元素,用{}数组的形式
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//默认是value可以不写,一般该注解是在runtime中
@Retention(RetentionPolicy.RUNTIME)
//Document将注解生成在Javadoc中
@Documented
//Inherited子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
//下面是注释的参数,不是方法
String name() default "yjj";
int age() default 0;
int id() default -1;//-1表示不存在
String[] schools() default {"北京大学","清华大学"};
}
反射Reflection
通过反射机制可以让Java具有一定的动态性。
- 动态语言:在运行时可以改变其结构的语言。可以在运行时引进新的函数、对象或者代码,原有函数可以被删除或者改变结构。比如外挂就改变了原函数
- 静态语言:运行时结构不可变。如java,c,c++
通过一个对象得到这个对象的类叫做反射
获取Class类的实例
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("这个人是"+person.name);
//1、通过对象获得
Class c1 = person.getClass();
System.out.println(c1);
//2、通过forname
Class c2 = Class.forName("com.yjj.reflection.Student");
System.out.println(c2);
//3、通过类名.class
Class c3 = Student.class;
System.out.println(c3);
//基本内置类型的包装类都有一个Type属性
Class c4 = Double.TYPE;
System.out.println(c4);//double
//获取父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public String name;
public int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
class Student extends Person{
public Student() {
this.name = "学生";
}
}
class Teacher extends Person{
public Teacher() {
this.name = "老师";
}
}
所有类型的Class
import java.lang.annotation.ElementType;
@SuppressWarnings("all")
public class Test02 {
public static void main(String[] args) {
Class c1 = Object.class;
Class c2 = Comparable.class;
Class c3 = String[].class;
Class c4 = int[][].class;
Class c5 = Override.class;
Class c6 = ElementType.class;//枚举类型
Class c7 = Integer.class;
Class c8 = void.class;//空类型
Class c9 = Class.class;
System.out.println(c1);//class java.lang.Object
System.out.println(c2);//interface java.lang.Comparable
System.out.println(c3);//class [Ljava.lang.String;
System.out.println(c4);//class [[I
System.out.println(c5);//interface java.lang.Override
System.out.println(c6);//class java.lang.annotation.ElementType
System.out.println(c7);//class java.lang.Integer
System.out.println(c8);//void
System.out.println(c9);//class java.lang.Class
//类型一样维度一样那么Class也就一样
int[] a = new int[10];
int[] b = new int[100];
int[][]aa = new int[10][10];
System.out.println(a.getClass());//class [I
System.out.println(b.getClass());//class [I
System.out.println(aa.getClass());//class [[I
}
}