Java二次复习笔记(1)

  1. Java采用的默认字符编码集是Unicode。
  2. byte=byte+byte报错,值为int,而byte+=byte不报错。同样short = short+short报错,值为int;short += short不报错。
  3. float和double小数计算有时会出现误差,原因是计算机底层为二进制,有些小数无法用二进制准确表示。如:0.5可以用2的-1次表示,0.3则无法用二进制表示。
  4. static方法是类级别的;非static方法是对象级别的。
    对象可以 -> new一个对象后,对象.static方法()或对象.非static方法()
    类只能 -> 类名.static方法
class Sta{
    public static void test01(){
        System.out.println("用类名直接调用static方法!");
    }
    public static void test02(){
        System.out.println("new一个对象后调用static方法!");
    }
}
public class Test {
    public static void test(){
        System.out.println("本类直接调用static方法!");
    }
    public static void main(String[] args) {
        test();
        Sta.test01();
        new Sta().test02();
    }
}

运行结果:

本类直接调用static方法!
用类名直接调用static方法!
new一个对象后调用static方法!
  1. 对于非基本类型(也叫对象类型或引用类型):
    只定义,不new:默认值为null。例如 Person p; String s; 其中p和s都为null。
    new实例化:Xxx xx = new Xxx(); xx值不是null,xx内部的属性值全部是数据类型的默认值。例如 String s = new String(); s为"",Person p = new Person(); p对象里的属性name为null,age为0,stature为0.0。
  2. 字符串。如果直接使用字面量(String s = "abc";),则从常量池中找;如果使用new(String s = new String("abc");),则从堆中找,而堆又会从常量池中找,如果常量池中不存在,则在常量池中创建,并引用该常量池中的字符串。
    ①问:String s = new String("hello");创建了多少个对象?答:如果之前常量池中不存在“hello”字符串,创建了两个对象(堆中+常量池中)+一个引用。如果之前常量池中存在“hello”字符串,则创建了一个对象(堆中)+一个引用。
    ②问:如果常量池为空,String s = new String("a"+"b");创建了多少个对象?答:创建了4个对象(堆中new的东西+常量池中"a"、"b"、"ab")。
  3. . String中的inter()方法,可以让引用直接指向常量池。例String s1="a"; String s2=new String("a"); 此时s1==s2为false,当s2=s2.inter();s1==s2为true。
  4. 字符串分割。split()方法有些符号(. | + 等等)是无法直接分割的,需要加两个转义字符\;也可以使用StringTokenizer token = new StringTokenizer(要分割的字符串,分割的符号);然后迭代while(token.hasMoreElements()) {System.out.println(token.nextElement());}实现分割。
import java.util.StringTokenizer;
public class Test {
    public static void main(String[] args) {
        String s = "abc+def";
        String[] splits = s.split("\\+");
        System.out.println(splits[0]+"\t"+splits[1]);
        
        StringTokenizer tokenizer = new StringTokenizer(s,"+"); 
        while (tokenizer.hasMoreElements()){    
            System.out.println(tokenizer.nextElement()); 
        } 
    }
}

运行结果:

abc def
abc
def
  1. 构造方法。如果类中没有构造方法,则系统自动提供一个无参构造方法,如果类中存在了任何构造方法,系统不再提供无参构造方法。this();调用本类构造,super();调用父类构造,只能放在第一行。建议:如果给类中编写构造方法,提前写一个无参构造防止报错。
  2. 子类继承父类。private属性的变量可以被继承,但是不能使用、构造方法是不能被继承的,但是子类可以显示调用父类构造->super(); 。
class F{
    private int age = 10;
    public F(){
        System.out.println(age);
        ff();
    }
    private void ff(){
        System.out.println("ff");
    }
    public void tt(){
        System.out.println("tt");
    }
}
class S extends F{
    public S(){
        super();
    }
}
public class Test {
    public static void main(String[] args) {
        new S().tt();
    }
}

运行结果:

10
ff
tt
  1. 实例化。当new Xxx();时经历了以下过程:测试类static静态代码块->父类static静态代码块->子类static静态代码块->父类普通代码块->父类无参->子类普通代码块->子类无参...
    静态代码块(static{ }):第一次执行且永远只执行一次。
    普通代码块({ }):每次执行无参构造之前执行。
class F{
    static {
        System.out.println("父类静态代码块");
    }
    {
        System.out.println("父类普通代码块");
    }
    public F(){
        System.out.println("父类构造方法");
    }
}
class S extends F{
    static {
        System.out.println("子类静态代码块");
    }
    {
        System.out.println("子类普通代码块");
    }
    public S(){
        System.out.println("子类构造方法");
    }
}
public class Test {
    static {
        System.out.println("测试类静态代码块");
    }
    {
        System.out.println("测试类普通代码块");
    }
    public static void main(String[] args) {
        new S();
        new S();
    }
}

运行结果:

测试类静态代码块
父类静态代码块
子类静态代码块
父类普通代码块
父类构造方法
子类普通代码块
子类构造方法
父类普通代码块
父类构造方法
子类普通代码块
子类构造方法
  1. 构造方法不能被重写(原因:重写必须是子类重写父类,构造方法不能被继承,所以不存在重写)。
    | | 位置 | 方法名 | 参数列表 | 返回值 | 访问修饰符 |
    | --- | --- | --- | --- | --- | --- |
    | 方法重写 | 子类 | 相同 | 相同 | 相同或子类 | 不能比父类更严格 |
    | 方法重载 | 同类或子类 | 相同 | 不相同 | 无关 | 无关 |
  2. 抽象类不能实例化,原因:抽象类中可能存在抽象方法,而抽象方法没有方法体。
  3. final关键字。final修饰的类不能被继承,final修饰的方法不能被重写,final修饰的变量、属性不能被修改。
  4. 多态。打:打篮球、打水、打架...
    多态:父类引用指向子类对象;引用在栈空间中,子类对象在堆空间中。
父类 引用对象名字 = new 子类();
Pet pet = new Dog();//多态
Pet pet = new Cat();//多态
double d = 10;//double = int(大范围类型 = 小范围类型)
  1. 继承: 子类 is a 父类 ->狗是一个宠物(狗是子类,宠物是父类)
    接口: 类 has a 接口 ->门有锁的功能(门是类,锁是接口)
  2. 接口。接口中没有方法体,且方法都默认为“public abstract”,属性都默认为“static final”。接口和抽象类一样,不能实例化。
  3. 子类必须重写父类中的所有抽象方法;实现类必须实现接口中的所有抽象方法。
  4. 包装类。
public class BZL {
    public static void main(String[] args) {
        int i = 10;
        Integer j = new Integer(20);
        i = j;  //自动装箱  底层使用的是intValue()
        j = i;  //自动装箱  底层使用的是valueOf()
        /*valueOf()该方法中有一个缓冲区【-128,127】,如果装箱的数字不在此范围内,要重新new一个对象*/
        Integer a = 100;
        Integer b = 100;
        Integer c = 1000;
        Integer d = 1000;
        System.out.println("a与b比较:"+ (a==b));
        System.out.println("c与d比较:"+ (c==d));
    }
}

运行结果:

a与b比较:true
c与d比较:false
  1. 集合。
    Collection 存储的数据 不唯一,无序,是List的父类,Collection接口的父类是Iterable接口。
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionTest {
    public static void main(String[] args) {
        Collection col = new ArrayList<>();
        Collection col1 = new ArrayList();
        //col.add();  添加元素
        col.add("a");
        col.add("b");
        col.add("c");
        System.out.println("col"+col);
        col1.add(1);
        col1.add(2);
        col1.add("3");
        System.out.println("col1"+col1);
        //迭代
        Iterator it = col.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();
            System.out.println(s);
        }
        //col.addAll();  添加一个集合所包含的全部元素
        col.addAll(col1);
        System.out.println("col:"+col);
        //col.toArray();  将集合转换为数组
        Object[] os = col.toArray();
        System.out.print("集合转数组:");
        for (int i = 0; i < os.length; ++i) {
            System.out.print(os[i]+"\t");
            if (i==os.length-1){
                System.out.println();
            }
        }
        //col.remove(Object o); 移除
        col.remove("b");
        System.out.println("移除后 col:"+col);
        //col.removeAll();  移除一个集合所包含的全部元素
        col.removeAll(col1);
        System.out.println("移除"+col1+"后col:"+col);
        col.addAll(col1);
        System.out.println("col:"+col);
        //col.retainAll();  只剩一个集合所包含的全部元素
        col.retainAll(col1);
        System.out.println("retainAll"+col1+"后col:"+col);
        //col.contain();  判断是否包含该元素
        System.out.println(col.contains("2"));
        System.out.println(col.contains(2));
        //col.containAll();  判断是否包含该集合
        System.out.println(col.containsAll(col1));
        System.out.println("判断集合是否为空:"+col.isEmpty());
        System.out.println("返回集合长度:"+col.size());
        System.out.println("返回集合哈希值:"+col.hashCode());
        //清空集合
        col.clear();
        System.out.println("col:"+col);
    }
}

运行结果:

col[a, b, c]
col1[1, 2, 3]
a
b
c
col:[a, b, c, 1, 2, 3]
集合转数组:a b c 1 2 3 
移除后 col:[a, c, 1, 2, 3]
移除[1, 2, 3]后col:[a, c]
col:[a, c, 1, 2, 3]
retainAll[1, 2, 3]后col:[1, 2, 3]
false
true
true
判断集合是否为空:false
返回集合长度:3
返回集合哈希值:30865
col:[]

List(ArrayList,LinkList)存储的数据是不唯一的,有序的(按存入顺序排),可以通过索引增删改查元素。

package collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
//List接口拥有Collection接口的所有功能
public class ListTest {
   public static void main(String[] args) {
       ArrayList list = new ArrayList();
       list.add("a");
       list.add("b");
       System.out.println("list:"+list);
       //add(int index,Object element);  index位置插入元素element
       list.add(0,"A");
       System.out.println("list:"+list);
       List list1 = new ArrayList();
       list1.add("F");
       list1.add("f");
       list1.add("B");
       //add(int index,Collection c);  index位置插入集合c
       list.addAll(1,list1);
       System.out.println("将集合"+list1+"插入1位置后list:"+list);
       //get();  返回某位置元素
       System.out.println("位置3的元素为:"+list.get(3));
       //indexOf(); 返回某元素首次出现的位置
       //lastIndexOf(); 返回某元素最后出现的位置
       System.out.println("b元素的位置:"+list.indexOf("b"));
       //remove(int index);  删除指定位置的元素
       list.remove(2);
       System.out.println("删除位置2处的元素后list:"+list);
       //set(int index,Object element);  index位置元素替换为元素element
       list.set(0,"OK");
       System.out.println("0位置元素替换为OK后,list:"+list);
       //subList(int fromIndex,int toIndex);  截取集合元素[fromIndex,toIndex)
       ArrayList list3 = new ArrayList(list.subList(1,3));
       System.out.println("截取list的[1,3):"+list3);
       LinkedList link = new LinkedList();
       link.add("a");
       link.add("b");
       link.addFirst("头");
       link.addLast("尾");
       System.out.println("link:"+link);
       //普通for循环遍历
       System.out.println("普通for循环遍历");
       for (int i=0;i<link.size();i++){
           System.out.println(link.get(i));
       }
       //增强for循环遍历
       System.out.println("增强for循环遍历");
       for (Object o:link){
           String s = (String)o;
           System.out.println(s);
       }
       //迭代器
       System.out.println("迭代器");
       Iterator iterator = link.iterator();
       while (iterator.hasNext()){
           String s = (String)iterator.next();
           System.out.println(s);
       }
   }
}

运行结果:

list:[a, b]
list:[A, a, b]
将集合[F, f, B]插入1位置后list:[A, F, f, B, a, b]
位置3的元素为:B
b元素的位置:5
删除位置2处的元素后list:[A, F, B, a, b]
0位置元素替换为OK后,list:[OK, F, B, a, b]
截取list的[1,3):[F, B]
link:[头, a, b, 尾]
普通for循环遍历
头
a
b
尾
增强for循环遍历
头
a
b
尾
迭代器
头
a
b
尾

Set(HashMap,TreeMap)存储的数据是唯一的,无序的。因为无序,所以无法通过索引 增删改查 元素。

package collection;
import java.util.HashSet;
import java.util.Iterator;
//Set接接口拥有Collection接口的所有功能
public class SetTest {
    public static void main(String[] args) {
        HashSet set = new HashSet();
        set.add("a");
        set.add("b");
        set.add("A");
        set.add("B");
        set.add("a");
        System.out.println(set);
        //增强for循环遍历
        System.out.println("增强for循环遍历");
        for (Object o :set) {
            String s = (String)o;
            System.out.println(s);
        }
        //迭代器遍历
        System.out.println("迭代器遍历");
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            String s = (String)iterator.next();
            System.out.println(s);
        }
    }
}

运行结果:

[a, A, b, B]
增强for循环遍历
a
A
b
B
迭代器遍历
a
A
b
B

Map(HashMap,TreeMap)无序的,key值是唯一的,value值不唯一。

package map;
import java.util.*;
//HashMap接口拥有Map接口的所有功能
//无序的:与存储顺序无关
public class MapTest {
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put("2","张三");
        map.put("1","李四");
        map.put("3","王五");
        map.put("A1","哈哈");
        System.out.println(map);
        //根据key找value
        System.out.println("key值为2的value值:"+map.get(2));
        System.out.println("集合长度:"+map.size());
        System.out.println("判断是否包含指定的key:"+map.containsKey(1));
        System.out.println("判断是否包含指定的value:"+map.containsValue("王五"));
        //转为只含key的单值集合(key值唯一,所以用Set)
        Set set = map.keySet();
        System.out.println(set);
        //转为只含value的单值集合(value值不唯一,所以用Collection)
        Collection coll = map.values();
        System.out.println(coll);
        //remove(key);  根据key删除元素,返回值为value
        map.remove(2);
        System.out.println("删除key值为2的元素:"+map);
        //增强for循环遍历--通过entry遍历
        System.out.println("增强for循环遍历--通过entry遍历");
        Set entries = map.entrySet();
        for(Object o:entries){
            Map.Entry et = (Map.Entry) o;
            Object k = et.getKey();
            Object v = et.getValue();
            System.out.println("key:"+k+"--"+"value:"+v);
        }
        //迭代器
        System.out.println("迭代器");
        Set keySet = map.keySet();
        Iterator iterator = keySet.iterator();
        while(iterator.hasNext()){
            Object k = iterator.next();
            Object v = map.get(k);
            String sk = (String)k;
            String sv = (String)v;
            System.out.println("key:"+sk+"--"+"value:"+sv);
        }
    }
}

运行结果:

{A1=哈哈, 1=李四, 2=张三, 3=王五}
key值为2的value值:null
集合长度:4
判断是否包含指定的key:false
判断是否包含指定的value:true
[A1, 1, 2, 3]
[哈哈, 李四, 张三, 王五]
删除key值为2的元素:{A1=哈哈, 1=李四, 2=张三, 3=王五}
增强for循环遍历--通过entry遍历
key:A1--value:哈哈
key:1--value:李四
key:2--value:张三
key:3--value:王五
迭代器
key:A1--value:哈哈
key:1--value:李四
key:2--value:张三
key:3--value:王五

泛型:

package generic;
import java.util.*;
class Person{
    private int id;
    private String name;
    private int age;
    private double height;
    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
    public Person(){}
    public Person(int id, String name, int age, double height) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.height = height;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }
}
public class Demo {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"张三");
        map.put(3,"王五");
        map.put(2,"李四");
        Set<Map.Entry<Integer, String>> entries = map.entrySet();
        for (Map.Entry<Integer,String> entry:entries){
            System.out.println("key = "+entry.getKey());
            System.out.println("value = "+entry.getValue());
        }
        List<Person> list = new ArrayList<>();
        Person p1 = new Person(1,"张三",20,1.78);
        Person p2 = new Person(3,"王五",25,1.69);
        Person p3 = new Person(2,"李四",22,1.88);
        list.add(p1);
        list.add(p2);
        list.add(p3);
        Iterator<Person> iterator = list.iterator();
        while (iterator.hasNext()){
            Person p = iterator.next();
            System.out.println(p);
        }
    }
}

运行结果:

key = 1
value = 张三
key = 2
value = 李四
key = 3
value = 王五
Person{id=1, name='张三', age=20, height=1.78}
Person{id=3, name='王五', age=25, height=1.69}
Person{id=2, name='李四', age=22, height=1.88}
  1. 集合删除(remove()):
    Collection中的类(List、Set),删除的返回值是boolean;
    Map中的类,是根据key删除,返回值是value。
  2. 工具类。(Arrays、Collections)
    数组工具类:
import java.util.Arrays;
public class ArraysTest {
    public static void getArr(int[] arr){
        for (int i=0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        int[] arr = {5,8,9,11,6,2,7,9};
        System.out.println("原数组:");
        getArr(arr);
        Arrays.sort(arr);
        System.out.println("数组排序:");
        getArr(arr);
        //二分查法, 必须先排序再二分查
        System.out.println("9的位置:"+Arrays.binarySearch(arr,9));
        Arrays.fill(arr,5);
        System.out.println("填充全部:");
        getArr(arr);
    }
}

运行结果:

原数组:
5 8 9 11 6 2 7 9 
数组排序:
2 5 6 7 8 9 9 11 
9的位置:5
填充全部:
5 5 5 5 5 5 5 5 

集合工具类:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("java");
        list.add("mysql");
        list.add("html");
        list.add("php");
        list.add("python");
        System.out.println(list);
        Collections.sort(list);
        System.out.println("字典排序:"+ list);
        System.out.println("最大值:"+Collections.max(list));
        System.out.println("最小值:"+Collections.min(list));
        //二分法查(使用前,必须保证集合元素是 自然有序的)
        System.out.println("\"php\"位置:"+Collections.binarySearch(list,"php"));
        Collections.shuffle(list);
        System.out.println("洗牌后:"+list);
        Collections.reverse(list);
        System.out.println("反转后:" + list);
        Collections.swap(list,1,2);
        System.out.println("1位置与2位置元素交换:" + list);
        Collections.replaceAll(list,"php","c++");
        System.out.println("新元素替换所有旧元素" + list);
        Collections.fill(list,"hello");
        System.out.println("填充全部:" + list);
    }
}

运行结果:

[java, mysql, html, php, python]
字典排序:[html, java, mysql, php, python]
最大值:python
最小值:html
"php"位置:3
洗牌后:[mysql, html, php, java, python]
反转后:[python, java, php, html, mysql]
1位置与2位置元素交换:[python, php, java, html, mysql]
新元素替换所有旧元素[python, c++, java, html, mysql]
填充全部:[hello, hello, hello, hello, hello]
  1. 异常。
    try{ }catch{ } 自己(当前方法)能够处理,使用try catch;
package exception;
public class ExceptionTest {
    public static void test01(){
        try{
            Object obj = null;
            obj.equals(""); //会出现空指针异常
        }catch (NullPointerException e){
            System.out.println("发生了空指针异常!");
        }catch (Exception e){
           e.printStackTrace();
        }finally{
            System.out.println("最终都会执行的地方!");
        }
    }
    public static int test02(){
        try{
           int[] i = new int[1];
//            System.exit(1);     //关闭虚拟机,直接终止,下面都不会运行
           i[1] = 5; //发生数组越界异常
            return 0;
        }
        //捕获时,先写范围小的类型,后写范围大的类型
        catch (NullPointerException e){
            System.out.println("发生了空指针异常!");
            return 1;
        }catch (Exception e){
            System.out.println("上面catch没捕获到后用这个捕获!");
            return 2;
        }finally {
            System.out.println("最终都会执行的地方!");
            //return 3;
        }
    }
    public static void main(String[] args) {
        test01();
        System.out.println("返回值是:"+test02());
    }
}

运行结果:

发生了空指针异常!
最终都会执行的地方!
上面catch没捕获到后用这个捕获!
最终都会执行的地方!
返回值是:2

throws 自己(当前方法)不能处理,上交个上级(方法调用处)处理,使用throws。
自定义异常:MyException.java

package exception;
public class MyException extends Exception {
   public MyException(String message){
       super(message);
   }
}

ThrowTest.java

package exception;
public class ThrowTest {
   //1.利用try catch处理异常
   public static void test01(){
       int age = 188;
       //约定年龄范围(0,120]
       if (age<=0 || age>120){
           try {
               throw new MyException("年龄不符!");
           } catch (MyException e) {
               e.printStackTrace();
           }
       }
   }
   //2.利用throws抛出异常
   public static void test02() throws MyException {
       int age = 188;
       //约定年龄范围(0,120]
       if (age<=0 || age>120){
           throw new MyException("年龄不符!");
       }
   }
   public static void main(String[] args) {
       test01();
       //对于用throws抛出异常的方法,调用时要么try catch,要么继续throws抛出
       try {
           test02();
       }catch (MyException e){
           e.printStackTrace();
       }
   }
}

运行结果:

exception.MyException: 年龄不符!
 at exception.ThrowTest.test01(ThrowTest.java:15)
 at exception.ThrowTest.main(ThrowTest.java:31)   ...
exception.MyException: 年龄不符!
 at exception.ThrowTest.test02(ThrowTest.java:26)
 at exception.ThrowTest.main(ThrowTest.java:34)   ...
  1. 内置注解
    @Override:可以确保重写的方法的确存在于父类或者接口中,可以有效的避免单词拼错等情况。
    @Deprecated:用于提示,该方法由于安全、性能问题等已经不推荐使用了。此外,在版本升级时,如果要计划删除一些方法,也通常会在下一个版本中将该方法加上@Deprecated,然后再在后续版本中删除。
    @SuppressWarnings(value="unchecked"):压制警告(一般不建议使用)。value值有unchecked,deprecation(忽略一些过期的API),unused(是否未被使用),fallthrough(switch是否一直往下执行而没有break),path(忽略堆路径不存在的检查),serialVersionUID(忽略一个类可以被序列化,但没有序列化的警告),all(忽略一切警告)。
  2. 元注解(修饰注解的注解)
    @Target:限制注解使用的位置(属性、方法、类),如果一个注解没有@Target描述,则该注解可以修饰任何类型的元素,如果有@Target修饰。该注解就只能用于被@Target修饰的地方。
public enum ElementType {
    /**  类,接口(包括注释类型)或枚举声明 */
   
    TYPE,
    /** 字段声明(包括枚举常量) */
    FIELD,
    /** 方法声明 */
    METHOD,
    /** 形式参数声明 */
    PARAMETER,
    /** 构造函数声明 */
    CONSTRUCTOR,
    /** 局部变量声明 */
    LOCAL_VARIABLE,
    /** 注释类型声明 */
    ANNOTATION_TYPE,
    /** 包声明 */
    PACKAGE,
    /**
     * 类型参数声明
     *
     * @since 1.8
     */
    TYPE_PARAMETER,
    /**
     * 使用类型
     *
     * @since 1.8
     */
    TYPE_USE,
    /**
     * 模块声明.
     *
     * @since 9
     */
    MODULE
}

@Retention:限制注解的生命周期

public enum RetentionPolicy {
    /**
     * 批注将被编译器丢弃。
     jvm直接将该注解丢弃
     */
    SOURCE,
    /**
     * 注释将由编译器记录在类文件中,但不必在运行时由VM保留。这是默认的行为。
     .java -> .class
     程序在编译时会使用注解,在运行时不会使用
     */
    CLASS,
    /**
     * 注释由编译器记录在类文件中,并在运行时由VM保留,因此可以通过反射方式读取它们。
     *
     * @see java.lang.reflect.AnnotatedElement
     程序在编译以及运行时。都会使用注解
     */
    RUNTIME
}

@Document:
默认情况下,javadoc不包含注解的解释,如果想在javadoc文档中也包含注解的说明,则需要使用@Document标注。
@Inherited:继承。如果A类有一个注解,B类继承A类时,默认不会继承该注解;如果该注解用@Inherited修饰,则就可以继承注解。


接下来举个例子:
先自定义一个注解

package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.FIELD,ElementType.METHOD}) //修饰注解,只能在属性、方法上使用
@Retention(RetentionPolicy.RUNTIME) //修饰注解,编译运行时都会使用注解
public @interface MyAnnotation {
    //String value(); //用定义方法的形式,定义了一个属性value
    //String[] value(); //数组形式
    String value() default "Hello"; //default指定了value默认值为H ello
    int age() default 24;
}

测试一下

package annotation;
import java.lang.annotation.Annotation;
public class AnnotationTest {
    @MyAnnotation
    @Deprecated
    public static void test() throws Exception {
        //获取  “类名” 的 “方法” 的 “注解”
        Annotation[] annotations = Class.forName("annotation.AnnotationTest").getMethod("test").getAnnotations();
        for (Annotation a: annotations) {
        /*注:如果元注解@Retention的值不为RetentionPolicy.RUNTIME,则会直接执行下面的else结果*/
            if (a instanceof MyAnnotation){ 
                System.out.println("获取自定义注解的value值:" + ((MyAnnotation)a).value() );
                System.out.println("获取自定义注解得到age值:" + ((MyAnnotation)a).age() );
            }else{
                System.out.println("@Deprecated");
            }
        }
    }
    public static void main(String[] args) throws Exception {
        test();
    }
}

运行结果:

获取自定义注解的value值:Hello
获取自定义注解得到age值:24
@Deprecated
 posted on 2020-06-19 23:38  小辰2715  阅读(121)  评论(0编辑  收藏  举报