10_特殊类

内部类的基本概念

普通内部类的定义

NormalOuter.java

package cn.itcast.day01.demo16;

import org.w3c.dom.ls.LSOutput;

public class NormalOuter {
    private int cnt = 1;

    public class NormalInner {
        private int ia = 2;

        public NormalInner() {
            System.out.println("普通内部类中的构造方法执行了!");
        }

        public void show() {
            System.out.println("这里是内部类中的show方法体");
            System.out.println("外部类的cnt的值为:" + cnt);
            System.out.println("内部类的ia的值为:" + ia);
        }
    }
}

NormalOuterTest.java

package cn.itcast.day01.demo16;

public class NormalOuterTest {
    public static void main(String[] args) {
        NormalOuter no = new NormalOuter();
        NormalOuter.NormalInner ni = no.new NormalInner();
        ni.show();
    }
}

编译并执行NormalOuterTest.java

普通内部类中的构造方法执行了!
这里是内部类中的show方法体
外部类的cnt的值为:1
内部类的ia的值为:2

普通内部类的使用方式

NormalOuter.java

package cn.itcast.day01.demo16;

import org.w3c.dom.ls.LSOutput;

public class NormalOuter {
    private int cnt = 1;

    public class NormalInner {
        private int ia = 2;
        private int cnt = 3;

        public NormalInner() {
            System.out.println("普通内部类中的构造方法执行了!");
        }

        public void show() {
            System.out.println("这里是内部类中的show方法体");
            System.out.println("外部类的cnt的值为:" + cnt);
            System.out.println("内部类的ia的值为:" + ia);
        }

        public void show2(int cnt) {
            System.out.println("形参变量cnt = " + cnt);
            System.out.println("内部类中cnt = " + this.cnt);
            System.out.println("外部类中cnt = " + NormalOuter.this.cnt);
        }
    }
}

NormalOuterTest.java

package cn.itcast.day01.demo16;

public class NormalOuterTest {
    public static void main(String[] args) {
        NormalOuter no = new NormalOuter();
        NormalOuter.NormalInner ni = no.new NormalInner();
        ni.show();
        ni.show2(666);
    }
}

编译并执行NormalOuterTest.java

普通内部类中的构造方法执行了!
这里是内部类中的show方法体
外部类的cnt的值为:3
内部类的ia的值为:2
形参变量cnt = 666
内部类中cnt = 3
外部类中cnt = 1

静态内部类的定义

StaticOuter.java:

package cn.itcast.day01.demo16;

public class StaticOuter {
    private int cnt = 1;
    private static int snt = 2;

    public static class StaticInner {
        private int ia = 3;

        public StaticInner() {
            System.out.println("这里是内部静态类的构造方法!");
        }

        public void show() {
            System.out.println("内部类中的ia = " + ia);
            System.out.println("外部类中的snt = " + snt);
            //System.out.println("外部类中的cnt = " + cnt); //Error:静态上下文中不能访问非静态的成员,因为此时可能还没有创建对象
        }
    }
}

StaticOuterTest.java:

package cn.itcast.day01.demo16;

public class StaticOuterTest {
    public static void main(String[] args) {
        StaticOuter.StaticInner ss = new StaticOuter.StaticInner();
        ss.show();
    }
}

执行并编译StaticOuterTest.java

这里是内部静态类的构造方法!
内部类中的ia = 3
外部类中的snt = 2

静态内部类的使用方式

StaticOuter.java

package cn.itcast.day01.demo16;

public class StaticOuter {
    private int cnt = 1;
    private static int snt = 2;

    public static void show() {
        System.out.println("这里是外部类的静态成员show方法!");
    }

    public void show2() {
        System.out.println("这里是外部类的非静态成员show2方法!");
    }

    public static class StaticInner {
        private int ia = 3;
        private static int snt = 4;

        public StaticInner() {
            System.out.println("这里是内部静态类的构造方法!");
        }

        public void show() {
            System.out.println("内部类中的ia = " + ia);
            System.out.println("外部类中的snt = " + snt);
            System.out.println("外部类中的cnt = " + new StaticOuter().cnt); // 对象层级的成员只能通过对象去访问
            StaticOuter.show();
        }

        public void show2(int snt) {
            System.out.println("内部类中的形参snt = " + snt);
            System.out.println("内部类中的成员snt = " + StaticInner.snt);
            System.out.println("外部类中的成员snt = " + StaticOuter.snt);
            new StaticOuter().show2();  // 静态成员不能访问非静态成员,如果非要访问非静态成员,只能通过创建对象去访问该对象的非静态成员
        }
    }
}

StaticOuterTest,java

package cn.itcast.day01.demo16;

public class StaticOuterTest {
    public static void main(String[] args) {
        StaticOuter.StaticInner ss = new StaticOuter.StaticInner();
        ss.show();
        System.out.println("-----------------------");
        ss.show2(5);
    }
}

编译并执行StaticOuterTest,java

这里是内部静态类的构造方法!
内部类中的ia = 3
外部类中的snt = 4
外部类中的cnt = 1
这里是外部类的静态成员show方法!
-----------------------
内部类中的形参snt = 5
内部类中的成员snt = 4
外部类中的成员snt = 2
这里是外部类的非静态成员show2方法!

局部(方法)内部类的定义

局部内部类:写在方法体内部的类,只能在当前方法体内部使用。

AreaOuter.java

package cn.itcast.day01.demo16;

public class AreaOuter {
    private int cnt = 1;

    public void show() {
        class AreaInner {
            private int snt = 2;

            public AreaInner() {
                System.out.println("这里是局部类的构造方法");
            }

            public void test() {
                System.out.println("外部类的成员cnt = " + cnt);
                System.out.println("内部类的成员snt = " + snt);
            }
        }

        AreaInner ai = new AreaInner();
        ai.test();
    }
}

AreaOuterTest.java

package cn.itcast.day01.demo16;

public class AreaOuterTest {
    public static void main(String[] args) {
        AreaOuter ao = new AreaOuter();
        ao.show();
    }
}

编译并执行AreaOuterTest.java

这里是局部类的构造方法
外部类的成员cnt = 1
内部类的成员snt = 2

局部内部类的使用方式

AreaOuter.java

package cn.itcast.day01.demo16;

public class AreaOuter {
    private int cnt = 1;

    public void show() {
        final int ic = 3; //final可以省略,但建议加上

        class AreaInner {
            private int snt = 2;

            public AreaInner() {
                System.out.println("这里是局部类的构造方法");
            }

            public void test() {
                System.out.println("外部类的成员cnt = " + cnt);
                System.out.println("内部类的成员snt = " + snt);

                // 当局部类中要使用成员方法中的局部变量时,java会将局部变量拷贝一份过来
                System.out.println("外部类的show方法中的局部变量ic = " + ic);
            }
        }

        AreaInner ai = new AreaInner();
        ai.test();
    }
}

回调模式的概念和编程

AnonymousInterface.java

package cn.itcast.day01.demo16;

public interface AnonymousInterface {
    public abstract void show();
}

AnonymousInterfaceImpl.java

package cn.itcast.day01.demo16;

public class AnonymousInterfaceImpl implements AnonymousInterface {

    @Override
    public void show() {
        System.out.println("这里是接口AnonymousInterface的实现类!");
    }
}

AnonymousInterfaceTest.java

package cn.itcast.day01.demo16;

public class AnonymousInterfaceTest {
    public static void test(AnonymousInterface ai) {
        ai.show();
    }

    public static void main(String[] args) {
        AnonymousInterfaceTest.test(new AnonymousInterfaceImpl());
    }
}

匿名内部类的语法格式

AnonymousInterfaceTest.java

package cn.itcast.day01.demo16;

public class AnonymousInterfaceTest {
    public static void test(AnonymousInterface ai) {
        ai.show();
    }

    public static void main(String[] args) {
        AnonymousInterfaceTest.test(new AnonymousInterfaceImpl());

        System.out.println("-----------------------------------");

        AnonymousInterface aii = new AnonymousInterface() {
            @Override
            public void show() {
                System.out.println("这里是重写后的匿名内部类的show方法");
            }
        };
        AnonymousInterfaceTest.test(aii);
    }
}

编译并执行AnonymousInterfaceTest.java

这里是接口AnonymousInterface的实现类!
-----------------------------------
这里是重写后的匿名内部类的show方法

使用lambda表达式也可以实现匿名内部类的功能:

AnonymousInterfaceTest.java

package cn.itcast.day01.demo16;

public class AnonymousInterfaceTest {
    public static void test(AnonymousInterface ai) {
        ai.show();
    }

    public static void main(String[] args) {
        AnonymousInterfaceTest.test(new AnonymousInterfaceImpl());

        System.out.println("-----------------------------------");

        //使用匿名内部类的语法格式来得到接口类型的引用
        AnonymousInterface aii = new AnonymousInterface() {
            @Override
            public void show() {
                System.out.println("这里是重写后的匿名内部类的show方法");
            }
        };

        //从java8开始提出新特性lambda表达式,可以简化上述代码
        AnonymousInterface aii2 = () -> System.out.println("使用lambda表达式重写AnonymousInterface的show方法!");

        AnonymousInterfaceTest.test(aii2);
    }
}

编译并执行AnonymousInterfaceTest.java

这里是接口AnonymousInterface的实现类!
-----------------------------------
使用lambda表达式重写AnonymousInterface的show方法

枚举类的概念和自定义实现

Direction.java

package cn.itcast.day01.demo17;

/**
 * 编程实现所有方向的枚举,所有方向包括:上、下、左、右
 */

public class Direction {
    private final String desc;

    //2、声明本类类型的引用指向本类类型的对象
    public static final Direction UP = new Direction("向上");
    public static final Direction DOWN = new Direction("向下");
    public static final Direction LEFT = new Direction("向左");
    public static final Direction RIGHT = new Direction("向右");

    //通过构造方法实现成员变量的初始化
    //1、私有化构造方法,此时该构造方法只能在本类内部使用
    private Direction(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }
}

DirectionTest.java

package cn.itcast.day01.demo17;

public class DirectionTest {
    public static void main(String[] args) {
        //只能获取固定数量的对象的类就是枚举类
        System.out.println(Direction.UP.getDesc());
        System.out.println(Direction.DOWN.getDesc());
        System.out.println(Direction.LEFT.getDesc());
        System.out.println(Direction.RIGHT.getDesc());
    }
}

编译并执行DirectionTest.java

向上
向下
向左
向右

枚举类型的定义

DirectionEnum.java

package cn.itcast.day01.demo17;

/**
 * 编程实现所有方向的枚举,所有方向包括:上、下、左、右
 */

public enum  DirectionEnum {
    UP("向上"),DOWN("向下"),LEFT("向左"),RIGHT("向右");

    private final String desc;

    //通过构造方法实现成员变量的初始化
    //1、私有化构造方法,此时该构造方法只能在本类内部使用
    private DirectionEnum(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }
}

DirectionTest.java

package cn.itcast.day01.demo17;

public class DirectionTest {
    public static void main(String[] args) {
        DirectionEnum UP = DirectionEnum.UP;
        DirectionEnum DOWN = DirectionEnum.DOWN;
        DirectionEnum LEFT = DirectionEnum.LEFT;
        DirectionEnum RIGHT = DirectionEnum.RIGHT;
        System.out.println(UP.getDesc());
        System.out.println(DOWN.getDesc());
        System.out.println(LEFT.getDesc());
        System.out.println(RIGHT.getDesc());
    }
}

编译并执行DirectionTest.java

向上
向下
向左
向右

自定义类和枚举类型在switch结构的使用

自定义类在switch结构的使用

Direction.java

package cn.itcast.day01.demo17;

/**
 * 编程实现所有方向的枚举,所有方向包括:上、下、左、右
 */

public class Direction {
    private final String desc;

    //2、声明本类类型的引用指向本类类型的对象
    public static final Direction UP = new Direction("向上");
    public static final Direction DOWN = new Direction("向下");
    public static final Direction LEFT = new Direction("向左");
    public static final Direction RIGHT = new Direction("向右");
    
    //通过构造方法实现成员变量的初始化
    //1、私有化构造方法,此时该构造方法只能在本类内部使用
    private Direction(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }
}

DirectionUseTest.java

package cn.itcast.day01.demo17;

public class DirectionUseTest {
    //自定义静态方法实现根据参数指定的字符串类型来打印具体的方向信息
    public static void test1(String str) {
        switch (str) {
            case "向上":
                System.out.println("抬头望明月");
                break;
            case "向下":
                System.out.println("低头思故乡");
                break;
            case "向左":
                System.out.println("左牵黄");
                break;
            case "向右":
                System.out.println("右擎苍");
                break;
            default:
                System.out.println("没有这样的方法哦!");
        }
    }

    public static void main(String[] args) {
        DirectionUseTest.test1(Direction.UP.getDesc());
        DirectionUseTest.test1(Direction.DOWN.getDesc());
        DirectionUseTest.test1(Direction.LEFT.getDesc());
        DirectionUseTest.test1(Direction.RIGHT.getDesc());
    }
}

编译并执行DirectionUseTest.java

抬头望明月
低头思故乡
左牵黄
右擎苍

枚举类型在switch结构的使用

DirectionEnum.java

package cn.itcast.day01.demo17;

/**
 * 编程实现所有方向的枚举,所有方向包括:上、下、左、右
 */

public enum  DirectionEnum {
    UP("向上"),DOWN("向下"),LEFT("向左"),RIGHT("向右");

    private final String desc;

    //通过构造方法实现成员变量的初始化
    //1、私有化构造方法,此时该构造方法只能在本类内部使用
    private DirectionEnum(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }
}

DirectionUseTest.java

package cn.itcast.day01.demo17;

public class DirectionUseTest {

    //自定义静态方法实现根据参数指定的字符串类型来打印具体的方向信息
    public static void test1(String str) {
        switch (str) {
            case "向上":
                System.out.println("抬头望明月");
                break;
            case "向下":
                System.out.println("低头思故乡");
                break;
            case "向左":
                System.out.println("左牵黄");
                break;
            case "向右":
                System.out.println("右擎苍");
                break;
            default:
                System.out.println("没有这样的方向哦!");
        }
    }

    //自定义静态方法实现根据参数指定的枚举类型来打印具体的方向信息
    public static void test2(DirectionEnum de) {
        switch (de) {
            case UP:
                System.out.println("抬头望明月");
                break;
            case DOWN:
                System.out.println("低头思故乡");
                break;
            case LEFT:
                System.out.println("左牵黄");
                break;
            case RIGHT:
                System.out.println("右擎苍");
                break;
            default:
                System.out.println("没有这样的方向哦!");
        }
    }

    public static void main(String[] args) {
        DirectionUseTest.test2(DirectionEnum.UP);
        DirectionUseTest.test2(DirectionEnum.DOWN);
        DirectionUseTest.test2(DirectionEnum.LEFT);
        DirectionUseTest.test2(DirectionEnum.RIGHT);
    }
}

编译并执行DirectionUseTest.java

抬头望明月
低头思故乡
左牵黄
右擎苍

Enum类的概念和常用方法

DirectionEnumTest.java

package cn.itcast.day01.demo17;

/**
 * 编程实现方向枚举类的测试
 */

public class DirectionEnumTest {
    public static void main(String[] args) {
        //1、获取DirectionEnum类型中所有的枚举对象
        DirectionEnum[] arr1 = DirectionEnum.values();

        //2、打印每个枚举对象在枚举类型中的名称和索引位置
        for (int i = 0; i < arr1.length; i++) {
            System.out.println("获取到的枚举对象名称是:" + arr1[i].toString() + ",对应索引位置是:" + arr1[i].ordinal());
        }

        System.out.println("----------------------------------------");

        //3、根据参数指定的字符串得到枚举类型的对象,也就是字符串转换为对象
        DirectionEnum de = DirectionEnum.valueOf("DOWN");
        System.out.println("转换出来的枚举对象名称是:" + de); //当打印引用变量是,会自动调用toString方法

        //4、使用获取到的枚举对象与枚举类中已有的对象比较先后顺序
        for (int j = 0; j < arr1.length; j++) {
            //当调用对象在参数对象之前时,获取到的比较结果是 正数
            //当调用对象在参数对象相同位置时,获取到的比较结果是 0
            //当调用对象在参数对象之后时,获取到的比较结果是 负数
            System.out.println("调用对象与数组中对象比较的先后顺序结果是:" + de.compareTo(arr1[j]));
        }
    }
}

编译并执行DirectionEnumTest.java

获取到的枚举对象名称是:UP,对应索引位置是:0
获取到的枚举对象名称是:DOWN,对应索引位置是:1
获取到的枚举对象名称是:LEFT,对应索引位置是:2
获取到的枚举对象名称是:RIGHT,对应索引位置是:3
----------------------------------------
转换出来的枚举对象名称是:DOWN
调用对象与数组中对象比较的先后顺序结果是:1
调用对象与数组中对象比较的先后顺序结果是:0
调用对象与数组中对象比较的先后顺序结果是:-1
调用对象与数组中对象比较的先后顺序结果是:-2

枚举类实现接口的方式

只重新一次

DirectionInterface.java

package cn.itcast.day01.demo17;

public interface DirectionInterface {
    public abstract void show();
}

DirectionEnum.java

package cn.itcast.day01.demo17;

/**
 * 编程实现所有方向的枚举,所有方向包括:上、下、左、右
 */

public enum DirectionEnum implements DirectionInterface{
    UP("向上"),DOWN("向下"),LEFT("向左"),RIGHT("向右");

    private final String desc;

    //通过构造方法实现成员变量的初始化
    //1、私有化构造方法,此时该构造方法只能在本类内部使用
    private DirectionEnum(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }

    //整个枚举类型只重写一次,所有对象调用同一个
    @Override
    public void show() {
        System.out.println("现在可以实现接口中抽象方法的重写了!");
    }
}

DirectionEnumTest.java

package cn.itcast.day01.demo17;

/**
 * 编程实现方向枚举类的测试
 */

public class DirectionEnumTest {
    public static void main(String[] args) {
        //1、获取DirectionEnum类型中所有的枚举对象
        DirectionEnum[] arr1 = DirectionEnum.values();

        //2、打印每个枚举对象在枚举类型中的名称和索引位置
        for (int i = 0; i < arr1.length; i++) {
            System.out.println("获取到的枚举对象名称是:" + arr1[i].toString() + ",对应索引位置是:" + arr1[i].ordinal());
        }

        System.out.println("----------------------------------------");

        //3、根据参数指定的字符串得到枚举类型的对象,也就是字符串转换为对象
        DirectionEnum de = DirectionEnum.valueOf("DOWN");
        System.out.println("转换出来的枚举对象名称是:" + de); //当打印引用变量是,会自动调用toString方法

        //4、使用获取到的枚举对象与枚举类中已有的对象比较先后顺序
        for (int j = 0; j < arr1.length; j++) {
            //当调用对象在参数对象之前时,获取到的比较结果是 正数
            //当调用对象在参数对象相同位置时,获取到的比较结果是 0
            //当调用对象在参数对象之后时,获取到的比较结果是 负数
            System.out.println("调用对象与数组中对象比较的先后顺序结果是:" + de.compareTo(arr1[j]));
        }

        System.out.println("----------------------------------------");

        for (int i = 0; i < arr1.length; i++) {
            arr1[i].show();
        }
    }
}

编译并执行DirectionEnumTest.java

获取到的枚举对象名称是:UP,对应索引位置是:0
获取到的枚举对象名称是:DOWN,对应索引位置是:1
获取到的枚举对象名称是:LEFT,对应索引位置是:2
获取到的枚举对象名称是:RIGHT,对应索引位置是:3
----------------------------------------
转换出来的枚举对象名称是:DOWN
调用对象与数组中对象比较的先后顺序结果是:1
调用对象与数组中对象比较的先后顺序结果是:0
调用对象与数组中对象比较的先后顺序结果是:-1
调用对象与数组中对象比较的先后顺序结果是:-2
----------------------------------------
现在可以实现接口中抽象方法的重写了!
现在可以实现接口中抽象方法的重写了!
现在可以实现接口中抽象方法的重写了!
现在可以实现接口中抽象方法的重写了!

每个对象都重写

DirectionInterface.java

package cn.itcast.day01.demo17;

/**
 * 编程实现所有方向的枚举,所有方向包括:上、下、左、右
 */

public enum DirectionEnum implements DirectionInterface{
    //匿名内部类的语法格式:public static final Direction UP = new Direction("向上");
    UP("向上") {
        @Override
        public void show() {
            System.out.println("贪吃蛇向上移动了一下!");
        }
    },DOWN("向下") {
        @Override
        public void show() {
            System.out.println("贪吃蛇向下移动了一下!");

        }
    },LEFT("向左") {
        @Override
        public void show() {
            System.out.println("左移了一下!");
        }
    },RIGHT("向右") {
        @Override
        public void show() {
            System.out.println("右移了一下!");
        }
    };

    private final String desc;

    //通过构造方法实现成员变量的初始化
    //1、私有化构造方法,此时该构造方法只能在本类内部使用
    private DirectionEnum(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }

    //整个枚举类型只重写一次,所有对象调用同一个
    /*@Override
    public void show() {
        System.out.println("现在可以实现接口中抽象方法的重写了!");
    }*/
}

DirectionEnumTest.java

package cn.itcast.day01.demo17;

/**
 * 编程实现方向枚举类的测试
 */

public class DirectionEnumTest {
    public static void main(String[] args) {
        //1、获取DirectionEnum类型中所有的枚举对象
        DirectionEnum[] arr1 = DirectionEnum.values();

        //2、打印每个枚举对象在枚举类型中的名称和索引位置
        for (int i = 0; i < arr1.length; i++) {
            System.out.println("获取到的枚举对象名称是:" + arr1[i].toString() + ",对应索引位置是:" + arr1[i].ordinal());
        }

        System.out.println("----------------------------------------");

        //3、根据参数指定的字符串得到枚举类型的对象,也就是字符串转换为对象
        DirectionEnum de = DirectionEnum.valueOf("DOWN");
        System.out.println("转换出来的枚举对象名称是:" + de); //当打印引用变量是,会自动调用toString方法

        //4、使用获取到的枚举对象与枚举类中已有的对象比较先后顺序
        for (int j = 0; j < arr1.length; j++) {
            //当调用对象在参数对象之前时,获取到的比较结果是 正数
            //当调用对象在参数对象相同位置时,获取到的比较结果是 0
            //当调用对象在参数对象之后时,获取到的比较结果是 负数
            System.out.println("调用对象与数组中对象比较的先后顺序结果是:" + de.compareTo(arr1[j]));
        }

        System.out.println("----------------------------------------");

        for (int i = 0; i < arr1.length; i++) {
            arr1[i].show();
        }
    }
}

编译并执行DirectionEnumTest.java

获取到的枚举对象名称是:UP,对应索引位置是:0
获取到的枚举对象名称是:DOWN,对应索引位置是:1
获取到的枚举对象名称是:LEFT,对应索引位置是:2
获取到的枚举对象名称是:RIGHT,对应索引位置是:3
----------------------------------------
转换出来的枚举对象名称是:DOWN
调用对象与数组中对象比较的先后顺序结果是:1
调用对象与数组中对象比较的先后顺序结果是:0
调用对象与数组中对象比较的先后顺序结果是:-1
调用对象与数组中对象比较的先后顺序结果是:-2
----------------------------------------
贪吃蛇向上移动了一下!
贪吃蛇向下移动了一下!
左移了一下!
右移了一下!

注解的基本概念

可以把枚举看作是一个特殊的类,把注解看作是一个特殊的接口。

注解的定义和使用

MyAnnotation.java

package cn.itcast.day01.demo17;

//若一个注解中没有任何成员,则这样的注解叫做标记注解/标识注解
public @interface MyAnnotation {
    public String value() default "默认值"; //声明一个String类型的成员变量,名字为value
    public String value2() default "默认值2";
}

Person.java

package cn.itcast.day01.demo17;

//标识将标签MyAnnotation贴在Person类的代码中,使用注解时采用 成员参数 = 成员参数值,...
@MyAnnotation(value = "hello", value2 = "world")
public class Person {
    private String name;
    private int age;
}

元注解的概念和@Retention的使用

MyAnnotation.java

package cn.itcast.day01.demo17;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

//@Retention(RetentionPolicy.SOURCE)   //表示下面的注解在源代码中有效
//@Retention(RetentionPolicy.CLASS)    //表示下面的注解在字节码文件中有效,默认方式
@Retention(RetentionPolicy.RUNTIME)    //表示下面的注解在运行时有效
public @interface MyAnnotation {
    public String value() default "默认值"; //声明一个String类型的成员变量,名字为value
    public String value2() default "默认值2";
}

@Documented的使用

Person.java

package cn.itcast.day01.demo17;

//标识将标签MyAnnotation贴在Person类的代码中,使用注解时采用 成员参数 = 成员参数值,...
@MyAnnotation(value = "hello", value2 = "world")
public class Person {
    /**
     * name是用于描述姓名的成员变量
     */
    private String name;
    /**
     * age是用于描述年龄的成员变量
     */
    private int age;

    /**
     * 编程实现无参构造方法
     */
    public Person() {
    }

    /**
     * 编程实现有参构造方法
     * @param name
     * @param age
     */
    public Person(String name, int age) {
        setName(name);
        setAge(age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age > 0 && age < 150) {
            this.age = age;
        } else {
            System.out.println("年龄不合法");
        }
    }
}

@Target@Inherited的使用

@Repeatable的使用

java8以前处理多个重复注解的方式

ManType.java:

ManTypes.java

Man.java

java8以后重复注解

ManTypes.java

ManType.java

Man.java

@Repeatable

ManType.java

ManTypes.java

Man.java

常见的预制注解

posted @ 2020-10-14 07:22  咕噜噜~  阅读(168)  评论(0编辑  收藏  举报