java 注解:SuppressWarnings、Deprecated、Override

Annotation注解在Java中有着很广泛的,他是做为一种标识 为javac所识别,。每一个注解 都对应这一个Java类  在java.lang包中 有三个注解  分别是
Deprecated    SuppressWarning   Override    在使用 注解前必须要在 注解类前面加上@    每增加一个注解 就意味着产生了一个注解对象 。
注解就是一个标识,编译器 通过标识来输出不同的编译结果  。    
Deprecated   过时的
SuppressWarning    抑制警告
Override    覆盖
比如@Deprecated   过时API注解   我们在用到JDK提供的API的时候,在编译中遇到 这样的提示 提示用到过时的API ,那么这个API 就被这个@Deprecated注解所 标识,在javac进行编译的时候  发现了注解便做出相应的提示 。
@SuppressWarning("deprecation")  从字面意思上就是抑制 过时API的警告,这个可以放在调用过时的API的方法外部或者调用方法之前,那么在编译的时候javac遇到这个标识 即使知道API过时那么也不会输出过时API的提示   
@Override 这个是覆盖注解,也就是在继承中进行覆盖 父类的某个方法的时候可以加上这个注解,加上这个注解之后 如果我们的覆盖方法 出错了Eclipse会提示我们错误


下面是简单的应用:
package me.test;
public class AnnotationTest  extends Test
{  

@SuppressWarnings("deprecation")
public static void main(String []aegs)
{  

  System.runFinalizersOnExit(true)  ;
  sayHello();
  AnnotationTest t=new AnnotationTest() ;
  t.show() ;
}
@Deprecated     //Deprecated  Annotation
public  static  void sayHello()
{
  System.out.println("hello ,world!");
}

    @Override
public  void  show()
{
  System.out.println("super class");
}

}
public class Test {
@Deprecated
public  void  show()
{
  System.out.println("super class");
}
}

public class Test {
public  void  show()
{
  System.out.println("super class");
}
}

什么是注解(Annotation),我们先来看如下代码:public class AnnotationTest {
public static void main(String[] args) {
  Date nowDate = new Date();
  String strDate = nowDate.toLocaleString();
  System.out.println(strDate);// 2009-12-27 16:44:09}
上述代码在eclipse编辑器中会出现警告,内容为"The method toLocaleString() from the type Date is deprecated",它的意思是说toLocaleString()方法是个过时的方法;
为了更好的理解它的含义,我们在cmd窗口来编译它,如下

java 注解:SuppressWarnings、Deprecated、Override

那么我们可以怎么把这个警告给去掉呢,这是就要使用到注解,我们在main方法之前加上这样一句"@SuppressWarnings("deprecation")",也可以用快捷方式加上,那么警告就会消失。public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
  Date nowDate = new Date();
  String strDate = nowDate.toLocaleString();
  System.out.println(strDate);// 2009-12-27 16:44:09}

注意:每个注解就是一个类,我们在用注解时,就相当于创建了一个注解类的实例;

2.在写程序中,我们可能不希望某个方法之后不被再次调用,那么我们就可以把这个方法定义为过时的方法,过时的方法在调用时,会在方法名上打上删除线,告诉程序员该方法为过时方法,最后不要再用了。下面我们写一个自定义的过时方法:public class AnnotationTest {

@Deprecated
private static void sayHello() {
  System.out.println("Hello word !");public static void main(String[] args) {
  AnnotationTest.sayHello();}

注意:只需要在方法前加上:@Deprecated,那么该方法就会被eclipse编辑器打上删除线,来表明为过时方法.

3.JDK为我们提供了如下3中基本的注解Annotation:
.Deprecated:用@Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。 
.Override:用@Override表示一个方法声明打算重写超类中的另一个方法声明。 
.SuppressWarnings:@SuppressWarnings("deprecation")指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。

4.注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,java编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事,标记可以加在包,类,字段,方法,方法的参数以及局部变量上。它位于java.lang.annotation中。

5.通常应用注解有如下三个步骤:
1).定义注解类,格式为:public @interface A{2).应用注解类,如:
@A
class B{3).对应用注解类的类进行反射操作(的类),如:
B.class.isAnnotationPresent(A.class);
A a = B.class.isAnnotationPresent(A.class);

6.下面我们来完成上述三步操作:
1).切换到java透视图上,点击新建一个注解:public @interface MyAnnotation {2).创建一个类应用该注解:
@MyAnnotation
public class AnnotationTest {
public static void main(String[] args) {}
3.对应用注解类的类进行反射操作:
public static void main(String[] args) {
  if (AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)) {
  MyAnnotation myAnnotation = AnnotationTest.class.getAnnotation(MyAnnotation.class);
  System.out.println(myAnnotation);}
注:这是程序运行没有输出,明明有注解,怎么会没输出呢?这时我们在MyAnnotation注解类前面加上:@Retention(RetentionPolicy.RUNTIME),再次运行时,就会输出"MyAnnotation"

7.下面我们来解释下什么叫Retention,Retention本身也是一个注解,叫元注解,它后面跟一个值,这个值表示该注解保留到代码的那个阶段;
@Retention元注解,有三种取值,即有三种生命周期:
RetentionPolicy.SOURCE:对应java源文件(如:@override、@superwarnings)
RetentionPolicy.CLASS:对应class文件
RetentionPolicy.RUNTIME:对应内存中的字节码(如:@Deprecated)
默然值就是RetentionPolicy.CLASS,在注解类上加的注解叫“元注解”,class文件本身不是字节码,只有class文件被类加载器被加载到内存中进行校检处理之后,才是二进制的字节码,他们的生命周期不是不同的。
注:如果我们把6中的RetentionPolicy.RUNTIME,改成其他两个中任何一个得话,也是无输出的,因外其他两个的注解生命周期不是运行期,即在内存中无法找到。

8.如果我们在MyAnnotation注解类前面再加上:@Target(ElementType.METHOD),那么AnnotationTest类前面就会有错误提示:"The annotation @MyAnnotation is disallowed for this location",即@MyAnnotation不能放在这个位置,为什么呢?因为刚才我们在MyAnnotation注解类前面再加上:@Target(ElementType.METHOD),它表示该注解只能用在方法上面,如果要想让该注解用的类上面,就可以不刚才那句修改成"@Target({ElementType.METHOD,ElementType.TYPE})",ElementType.TYPE它表示该注解可以应用的类,接口,枚举等类型上。

9.注解的高级应用-为注解增加属性,我们在刚才的MyAnnotation注解类增加一个属性,代码如下:@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
String color();那么此时,我们就会发现,AnnotationTest类的上面有错误提示“The annotation @MyAnnotation must define the attribute color”,即必定义color的属性,我们此时就可以把类上面的注解修改成:@MyAnnotation(color="red"),OK了!说明注解类有属性时,在我们调用时就必须提供属性值,除非注解类中的属性有默认值,@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
String color() default "yellow";调用的时候就可以直接:@MyAnnotation或@MyAnnotation();

再如代码:
public @interface MyAnnotation {
String color() default "yellow";
String style();调用的时候就可以直接: @MyAnnotation(color="red",style="fashion")或@MyAnnotation(style="fashion");有默认值的时候,默认值可以省略。

但是通常我们有如下用法:
@SuppressWarnings("deprecation"),它怎么只提供属性值,而没有属性名呢?这就是value()属性的特殊用法,它可以放回任意类型;

再如代码:
public @interface MyAnnotation {
String color() default "yellow";
String style() default "fashion";
String value();调用的时候就可以直接: @MyAnnotation(color="red",style="fashion",value="hello")
或@MyAnnotation("hello");

10.为注解增加高级属性,如数组,枚举,注解,具体就不再举例了,可以参考java语言规范中的实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JAVA高级特性 1.静态导入:先举个离例子 。 import java.lang.Integer.parseInt; public class StaticImport { int x = parseInt("123"); System.out.println(x); } 这样的程序如果不在IDE 工具中输入,是很难看出这个程序代码会出现问题,可它偏偏就出问题了,这是为什么呢?因为程序里面有个静态方法,如果导入import static java.lang.Integer.parseInt;这样的程序就可以运行了。 2.可变参数与for循环增强 这个是一般的用法: public static void loop(String[] args){ for(int i=0;i<args.length;i++) { System.out.println(args[i]); } } 这个是JDK 增加的新特性的用法! public static void loop(int x,int... args ) { //这里的参数一定要以这样的形式输入 for(int i:args) { System.out.println(i); } } 3.枚举 写枚举技巧: 1. enum Gender{MALE,FEMALE,BOTH} 2. enum Gender{MALE,FEMALE,BOTH;public abstract getTitle();} 3.enum Gender{MALE{},FEMALE{},BOTH{};public abstract getTitle();} 4.填充各个{}中的getTitle方法。 下面是个红绿黄灯的例子: public enum TrafficLamp { RED(30){ public TrafficLamp next() { return GREEN; } }, GREEN(50){ public TrafficLamp next() { return YELLOW; } }, YELLOW(5){ public TrafficLamp next() { return RED; } }; public abstract TrafficLamp next(); private int time; private TrafficLamp(int time) { this.time = time; } 4.反射. 这个知识点,真是费了我好大劲才理解。当真正理解了,其实也就不难了。先举例子来理解什么是反射。 先建这样的一个类,带会下面有个类里面有反射成员变量的方法的! public class ReflectPoint { private int x; public int y; public ReflectPoint(int x, int y) { super(); this.x = x; this.y = y; } } public class Test{ String obj = (String)Class.forName("java.lang.String").newInstance(); 这是制造另一个章:Class.forName("java.lang.Integer") --------------------- 讲Constructor://构造方法 Constructor constructors[] = Class.forName("java.lang.String").getConstructors(); Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class); String str = (String)constructor.newInstance(new StringBuffer("abc")); System.out.println(str); class.newInstance()内部其实就是在用默认的构造方法 ----------------------- 讲Method //方法 Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class); System.out.println(charAt.invoke(str, 1)); ------------------------- 讲Field //成员变量 ReflectPoint point = new ReflectPoint(1,7); Field y = Class.forName("cn.itcast.corejava.ReflectPoint").getDeclaredField("y"); y.setAccessible(true); System.out.println(y.get(point)); Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getDeclaredField("x"); x.setAccessible(true); System.out.println(x.get(point)); } 在这里我们运行的时候可以看出,ReflectPoint类里面的x和y 都可以打印出来了! 学习心得:先从这四个知识点来看,张老师的确很让人敬佩!以上的一些程序代码均为张老师课堂即兴发挥所写,也可以看出,张老师对JAVA特性的深刻理解能力!现在说说我对这些程序代码的理解,说实话,才开始听张老师讲的时候,我感觉很模糊的,但是当我真正理解了之后,觉得这些程序写的真是太好了。象以后我门在学习JAVA 的时候,一定要对每个知识点要慢慢的消化吃透,切不能走马观花。一个知识点必须要反复的动手练习,不然很难理解其中的奥秘所在的! 5.在JAVA的程序中,我经常性的看到字符前面有@这种标志的符号.这个就叫做注解! 下面是使用 @SuppressWarnings 来取消 deprecation 警告的一个例子: public class Test { @Deprecated //在eclipse下运行的时候,方法名上会加一横线 public static void sayHello() { } } public class Test2 { @SuppressWarnings("deprecation") //在mian方法内调用一个没有定义的方法时,运行的时候将会出现这一注解! public static void main(String [] args) { Test.sayHello(); } } @SuppressWarnings 批注允许您选择性地取消特定代码段(即,类或方法)中的警告。其中的想法是当您看到警告时,您将调查它,如果您确定它不是问题,您就可以添加一个 @SuppressWarnings 批注,以使您不会再看到警告。虽然它听起来似乎会屏蔽潜在的错误,但实际上它将提高代码安全性,因为它将防止您对警告无动于衷 — 您看到的每一个警告都将值得注意。 由如下代码引出@Override的讲解: User类中的方法: public boolean equals(User other) { return name.equals(other.name); } 下面的代码执行时将有问题: User user1 = new User(); User user2 = new User(); user1.setName("abc"); user2.setName("abc"); System.out.println(user1.equals(user2)); HashSet set = new HashSet(); set.add(user1); set.add(user2); System.out.println(set.size());//期望结果为1,但实际为2 这时候在User类的equals方法上加上@Override,发现了问题。 再看看这个代码:一看就知道有问题, 这里 就有个很好的解决办法,在写public @interface MyAnnotation {}这样的类的时候,下面的代码上的错误提示就是结束的! public class dsds { public static void main(String[] args) throws Exception{ // TODO Auto-generated method stub System.out.println(User.class.isAnnotationPresent(MyAnnotation.class) ); System.out.println( User.class.getAnnotation(MyAnnotation.class) ); } } 运行的结果为:false null 下面演示了一下@Target和@Retention import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE}) //用于构造方法 @Retention(RetentionPolicy.RUNTIME) //在运行是加载Annotation到JVM中 public @interface MyAnnotation { public String value() default "yellow"; public int[] array() default {1,2}; public MetaAnnotation annotation() ; } 注解最主要的就是这么多,其实注解真正的,我们都很少留心的,但是有的注解会给你在写程序和查找错误的时,会有很大的帮助的! 6.泛型: 1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。 2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。 3、泛型的类型参数可以有多个。 4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上成为“有界类型”。 5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName(java.lang.String); 例子: a..使用?通配符可以引用其他各种参数化的类型,但不能调用与参数化有关的方法; Collection<?> c = new Vector<String>(); c.add("abc");//报错 c.size();//正确 所以,?通配符定义的变量主要用作引用,调用与参数化无关的方法,如果要调用与参数化相关的方法,那么必须在使用?通配符引用之前调用,否则就与java 5提供泛型的目的背道而驰了。 b..向下限定通配符: 正确:Vector<? extends Number> x = new Vector<Integer>(); 错误:Vector<? extends Number> x = new Vector<String>(); 向上限定通配符: 正确:Vector<? super Integer> x = new Vector<Number>(); 错误:Vector<? super Integer> x = new Vector<Byte>(); 7.代理 这里就直接先应用张老师写的代码然后再讲清其原理吧! package cn.itcast.corejava; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Collection; import java.util.Vector; public class ProxyTest { public static void main(String[] args) { System.out.println(Integer.class.getClassLoader()); //System.out.println(ProxyTest.class.getClassLoader().getParent().getClass().getName()); System.out.println(ProxyTest.class.getClassLoader().getClass().getName()); //test1(); //test2(); } private static void test3() { Vector v = new Vector(); class MyInvocationHandler implements InvocationHandler { Collection target = null; public Collection bind(Collection target) { this.target = target; Collection proxy1 = (Collection)Proxy.newProxyInstance( ProxyTest.class.getClassLoader(), new Class[]{Collection.class} , this); return proxy1; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println("begin " + method.getName()); Object retval = method.invoke(target, args); System.out.println("end" + method.getName()); return retval; } } MyInvocationHandler handler = new MyInvocationHandler(); Collection proxy1 = handler.bind(v); System.out.println(proxy1.getClass().getName()); proxy1.add("abc"); proxy1.add("xyz"); System.out.println(proxy1.size()); } private static void test2() { Vector v = new Vector(); class MyInvocationHandler implements InvocationHandler { Collection target = null; public MyInvocationHandler(){} public MyInvocationHandler(Collection target){this.target = target;} public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println("begin " + method.getName()); Object retval = method.invoke(target, args); System.out.println("end" + method.getName()); return retval; } } Collection proxy1 = (Collection)Proxy.newProxyInstance( ProxyTest.class.getClassLoader(), new Class[]{Collection.class} , new MyInvocationHandler(v)); System.out.println(proxy1.getClass().getName()); proxy1.add("abc"); proxy1.add("xyz"); System.out.println(proxy1.size()); } private static void test1() { Collection proxy = (Collection)Proxy.newProxyInstance( ProxyTest.class.getClassLoader(),//first parameter new Class[]{Collection.class} , //second parameter new InvocationHandler(){ //third parameter Vector target = new Vector(); public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println("begin " + method.getName()); Object retval = method.invoke(target, args); System.out.println("end" + method.getName()); return retval; } } ); System.out.println(proxy.getClass().getName()); proxy.add("abc"); proxy.add("xyz"); System.out.println(proxy.size()); } } 以下是Proxy的API文档: public class Proxyextends extends Object implements Serializable Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods. To create a proxy for some interface Foo: InvocationHandler handler = new MyInvocationHandler(...); Class proxyClass = Proxy.getProxyClass( Foo.class.getClassLoader(), new Class[] { Foo.class }); Foo f = (Foo) proxyClass. getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler }); or more simply: Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[] { Foo.class }, handler);从以上的程序中在方法中定义参数的时候总是三个参数,可这三个参数有分别代表什么意思呢!?现在以我自己个人的理解,比如我是买家,我要买本书,可是现在我有事,是不是需要别人代我买呢?那带我买的人是不是一定要到卖书的地方买呢?所以着中间产生了三个实体.说白了就是一种代理机制.需要三方一起运行! 代理其实很好理解的,而且会用固定的语法格式,很快会掌握这一原理的!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值