使用注解标记字段和方法,可通过反射的手段截取注解及其标记的字段和方法的元数据,并根据需求对元数据进行处理。
它赋予了字段和方法额外的意义,提供了一种统一处理字段和方法的优雅的方式。
注解更多的意义是提供了一种设计模式,在本质上它没有增强Java的能力,使用注解实现的功能都可以以非注解的方式实现,只是代码可能不是很好看而已
package demo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* 注解(Annotation):
*
* 注解是JDK5.0及以后版本引入的。
* 它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。
* 注解是以‘@注解名’在代码中存在的,根据注解参数的个数,我们可以将注解分为:标记注解、单值注解、完整注解三类。
* 它们都不会直接影响到程序的语义,只是作为注解(标识)存在,我们可以通过反射机制编程实现对这些元数据(用来描述数据的数据)的访问。
* 另外,你可以在编译时选择代码里的注解是否只存在于源代码级,或者它也能在class文件、或者运行时中出现(SOURCE/CLASS/RUNTIME)
*/
@MyAnnotation(color = "red",value="11")//给color赋值会覆盖默认值,而且在类上赋的值会覆盖方法上的赋值
public class AnnotationDemo extends Thread{
@MyAnnotation("22")//因为其他的有默认值这里可以只给value赋值
public static void main(String[] args) {
//先判断是否为注解
if(AnnotationDemo.class.isAnnotationPresent(MyAnnotation.class)){
//使用反射获取注解
MyAnnotation anno = AnnotationDemo.class.getAnnotation(MyAnnotation.class);
//打印注解的值
System.out.println(anno.color()+anno.value());
}
}
//忽略已过时方法的警告
@SuppressWarnings("deprecation")
public static void overTime() {
System.runFinalizersOnExit(true);
}
//将方法标识为已过时的
@Deprecated
public void myPrint(){
System.out.println("hello world");
}
//标识重写方法
@Override
public void run() {
System.out.println("hello world");
}
}
//元注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@interface MyAnnotation{
//为注解添加属性
String color() default "blue";
String value();
int[] array() default {1,2,3};
}
下面是泛型的部分
package generic;
/**
* 泛型类
*
* 泛型:JDK1.5后出现的新特性,用以解决集合元素类型不一致造成的安全问题
* 优点: 1.将运行时检查的ClassCastException异常转到编译时检查。
* 2.避免的强制转换的麻烦
*
* 1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
* 2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
* 3、泛型的类型参数可以有多个。
* 4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上称为“有界类型”。
* 5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName("java.lang.String");
*/
public class GenericClassDemo {
public static void main(String[] args) {
//使用了指定对象的工具类,该工具类只支持该类对象
Tools t = new Tools();
t.setWorker(new Worker());
Worker w = t.getWorker();
w.work();
//使用接收Object的工具类
Tools2 t2 = new Tools2();
t2.setObject(new Worker());
//但在生成对象时需要强转,有安全隐患
Worker w2 = (Worker)t2.getObject();
w2.work();
//使用泛型在调用工具类时,事先指定操作类型
Tools3<Worker> t3= new Tools3<Worker>();
t3.setObject(new Worker());
Worker w3 = t3.getObject();
w3.work();
}
}
//假设要使用工具类,创建该对象,那么看看下面那种工具类更好
class Worker{
public void work(){
System.out.println("work");
}
}
//下面就通过例子对比,感受一下泛型的好处
//指定类型的工具类,但类型单一,对于当前的问题是解决了,但是如果有更多的类的话,就需要写出更多的相应类型的工具类了
class Tools{
private Worker w;
public void setWorker(Worker w){
this.w = w;
}
public Worker getWorker(){
return w;
}
}
//可以接受所有类型的工具类,但使用时需要强转,每次使用他的时候都需要强转成所要的类型,但这样虽然通过了编译,却可能会有安全隐患(强制转换异常)
class Tools2{
private Object obj;
public void setObject(Object obj){
this.obj = obj;
}
public Object getObject(){
return obj;
}
}
//泛型类,根据需要传入指定类型,即可作为该类型的工具类,泛型的使用使得工具类可以接受更多的类型,并避免了安全隐患
class Tools3<T>{
private T t;
public void setObject(T t){
this.t = t;
}
public T getObject(){
return t;
}
}