Java基础—枚举、注解、泛型、反射

一、枚举

当需要定义一组常量时,强烈建议使用枚举类

类的对象只有有限个、且是确定的

public class enumTest {

    public enum SeasonEnum {
        SPRING("春天","春风又绿江南岸"),
        SUMMER("夏天","映日荷花别样红"),
        AUTUMN("秋天","秋水共长天一色"),
        WINTER("冬天","窗含西岭千秋雪");
        private final String seasonName;
        private final String seasonDesc;
        private SeasonEnum(String seasonName, String seasonDesc) {
            this.seasonName = seasonName;
            this.seasonDesc = seasonDesc;
        }
        public String getSeasonName() {
            return seasonName;
        }
        public String getSeasonDesc() {
            return seasonDesc;
        }
    }

    public static void main(String[] args) {
        SeasonEnum autumn = SeasonEnum.AUTUMN;
        System.out.println(autumn.getSeasonDesc());

        System.out.println("================");
        //遍历 枚举类所有元素
        SeasonEnum[] values = SeasonEnum.values();
       for (SeasonEnum seasonEnum:values){
           System.out.println(seasonEnum);
       }

        System.out.println("================");
        //字符串转枚举对象
        SeasonEnum SPRING = SeasonEnum.valueOf("SPRING");
        System.out.println(SPRING.getSeasonDesc());
    }

}
/*
秋水共长天一色
================
SPRING
SUMMER
AUTUMN
WINTER
================
春风又绿江南岸
*/

说明:

  1. 使用 enum 定义的枚举类默认继承了 java.lang.Enum类,因此不能再继承其他类
  2. 枚举类的构造器只能使用 private权限修饰符 防止被其他人创建对象
  3. 枚举类的所有实例必须在枚举类中显式列出(, 分隔 ; 结尾)。列出的实例系统会自动添加 public static final 修饰
  4. 必须在枚举类的第一行声明枚举类对象

二 、注解(Annotation)

        注解就是代码里的特殊标记,可以在编译、类加载、运行时读取,并执行相应的处理。注解可以像修饰符一样使用,用于修饰包、类、构造器、方法、成员变量、参数等。

一定程度上:框架 = 注解 + 反射+设计模式

2.1 jdk内置的三个注解

@Override 重写父类方法

@Deprecated 标注已经过时的方法

@SuppressWarnings 抑制编译器警告    @SuppressWarnings("unuserd") 

2.2 jdk的四个元注解

用于修饰其他自定义Annotation

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})//用于指定能修饰哪些元素类型 字段 方法 类

@Retention(RetentionPolicy.RUNTIME)//运行期间保留 //指明注解的生命周期 RetentionPolicy.SOURCE 编译期间丢失;RetentionPolicy.CLASS class文件期间保留

@Documented 提渠道JavaDoc文档

@Inherited   具有继承性

使用 @interface 关键字

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})//用于指定能修饰哪些元素类型  字段  方法 类
@Retention(RetentionPolicy.RUNTIME)//运行期间保留 //指明注解的生命周期 RetentionPolicy.SOURCE 编译期间丢失;RetentionPolicy.CLASS class文件期间保留
public @interface MyAnnotation {
    // 成员属性  类型String 变量名value  默认值hello
    String value() default "hello";

}

三、泛型

        泛型 即允许在声明变量、创建对象时确认实际得参数类型。如果不使用泛型,而用Object得话,需要强转,并且可能出错。

// T表示类型。这里使用任意字母都可以
public class generics<T> {

    private T testObj;

    public T getTestObj() {
        return testObj;
    }

    public void setTestObj(T testObj) {
        this.testObj = testObj;
    }

    public static void main(String[] args) {
        //一定要在类名后面指定类型参数的值  不能用基本数据类型填充。但可以使用包装类填充
        generics<Float> floatTest = new generics<Float>();

        generics<Boolean> booleangenerics = new generics<Boolean>();

        floatTest.setTestObj(1.0f);
        booleangenerics.setTestObj(true);
        System.out.println(floatTest);
        System.out.println(booleangenerics);
    }
}

限制泛型可用类型  <T extends List> 则实现类必须是继承List

四、反射

 反射机制允许在运行期间根据对象获取类得内部信息,包括属性及方法。反射的应用场景:动态性  不知道是那个类。

4.1 基本使用

public class fansheTestNew {
    private String name;
    public int age;
    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;
    }

    @Override
    public String toString() {
        return "fansheTestNew{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public fansheTestNew(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private fansheTestNew(String name){
        this.name = name;
    }

    public void show(){
        System.out.println("无参的show方法");
    }

    public void show(String msg){
        System.out.println(this.name+"有参的show方法"+msg);
    }

    public static void main(String[] args) throws Exception{
        //此时 类fansheTestNew就是Class的一个实例
        Class clazz = fansheTestNew.class;
        //获取类的构造器
        Constructor constructor = clazz.getConstructor(String.class, int.class);
        Object tom = constructor.newInstance("Tom", 12);
        fansheTestNew tom1 = (fansheTestNew)tom;
        System.out.println(tom1.toString());

        //根据名称 获取属性
        Field age = clazz.getDeclaredField("age");
        age.set(tom1,25);//修改tom1对象的age属性
        System.out.println(tom1.toString());

        //根据方法名和参数类型 获取方法
        Method show = clazz.getDeclaredMethod("show", String.class);
        //执行tom1对象的方法
        show.invoke(tom1,"你好");

        //获取类的私有结构 如私有的构造器、方法、属性
        Constructor constructor1 = clazz.getDeclaredConstructor(String.class);
        constructor1.setAccessible(true);
        Object jerry = constructor1.newInstance("jerry");
        fansheTestNew jerry1 = (fansheTestNew)jerry;
        System.out.println(jerry1.toString());
        //获取私有的属性
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(jerry1,"mike");
        System.out.println(name);

    }
}

4.2 获取Class实例的四种方式

public static void main(String[] args) throws ClassNotFoundException {
        //方式一 类.class
        Class<fansheTestNew> clazz1 = fansheTestNew.class;
        //方式二 对象.getClass
        fansheTestNew obj = new fansheTestNew("ali",12);
        Class clazz2 = obj.getClass();
        //方式三  全路径名
        Class clazz3 = Class.forName("main.FirstDemo.zhujie.fansheTestNew");

        //方式四 类的加载器
        ClassLoader classLoader = obj.getClass().getClassLoader();
        Class clazz4 = classLoader.loadClass("main.FirstDemo.zhujie.fansheTestNew");

        System.out.println(clazz1 == clazz2 );
        System.out.println(clazz1 == clazz3 );
        System.out.println(clazz1 == clazz4 );
//均为true
    }

类加载的作用:将class文件字节码内容加载到内存中,并将静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的Class对象,作为方法区中类数据的访问入口。一旦某个类被加载到类加载器中,它将维持加载一段时间。不过JVM垃圾回收机制可以回收这些Class对象。

4.3 加载配置文件的两种方式

public class test1 {
    public static void main(String[] args) throws IOException {
        Properties pro = new Properties();
        //方式1  直接加载文件流  此时默认路径是module下
        FileInputStream fis = new FileInputStream("service1.properties");
        pro.load(fis);

        ClassLoader classLoader = test1.class.getClassLoader();
        // 加载方式2   直接通过反射  或者  先获得类加载器,最终都是通过类的加载器的方法
        //此时默认路径是 module/src/resource下
        InputStream resourceAsStream1 = test1.class.getResourceAsStream("service1.properties");
        InputStream resourceAsStream = classLoader.getResourceAsStream("service1.properties");
        pro.load(resourceAsStream);

        
        System.out.println(pro.getProperty("user"));

    }
}

4.4 反射获取类的信息结构

public class fansheTest2 {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;

        //获取当前类 及其父类的public属性字段
        Field[] fields = personClass.getFields();
        for(Field field:fields){
            System.out.println(field);
        }
        // 获取自身所有权限的属性字段 不包括父类的
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field field:declaredFields){
            // 获取权限修饰符  返回数字
            int modifiers = field.getModifiers();

            //获取数据类型 int String
            String name = field.getType().getName();

            //获取变量名
            String name1 = field.getName();

            System.out.println(field);
        }

        //获取当前类及其父类的 所有public方法
        Method[] methods = personClass.getMethods();

        //获取当前类的所有方法  包括私有方法
        Method[] declaredMethods = personClass.getDeclaredMethods();

        //获取每个方法上的 所有注解
        for (Method m: declaredMethods){
            //获取权限修饰符
            int modifiers = m.getModifiers();

            // 获取方法的返回值类型
            String name = m.getReturnType().getName();
            //获取方法名
            String name1 = m.getName();
            // 获取形参列表
            m.getParameters();
            //只能获取 runtime的注解
            Annotation[] annotations = m.getAnnotations();
            for(Annotation annotation:annotations){
                System.out.println(annotation);
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值