枚举类、注解、***反射

目录

1.枚举类

1.1 自定义枚举类

1.2 jdk5.0之后,可以使用enum关键字定义枚举类

2.注解

2.1 内置注解

2.2 元注解​编辑

2.3 自定义注解

3.反射

3.1 Java反射机制概述

3.2 理解Class类并获取Class实例

3.2.1自定义的类获取Class对象

3.2.2 所有类型的Class对象

3.3 类的加载与ClassLoader

3.3.1 类的加载过程

3.3.2 什么时候发生类的初始化

3.3.3 类加载器

3.4 获取运行时类的完整结构

3.5 调用运行时类的指定结构

3.5.1 通过反射创建对象、调方法、造作属性

3.5.2 性能测试

3.5.3获取泛型信息

3.6练习反射操作注解​编辑


1.枚举类

1.1 自定义枚举类

public class Season {

    //1.声明枚举类的属性
    //有限个对象 private,对象属性不可变 final
    private final String seasonNamae;
    private final String seasonDesc;

    //2.构造方法私有化,给成员变量赋值
    //保证对象是有限个:private
    private Season(String seasonNamae, String seasonDesc) {
        this.seasonNamae = seasonNamae;
        this.seasonDesc = seasonDesc;
    }

    //3.罗列枚举项
    public static final Season SPRING = new Season("春天", "春暖花开");
    public static final Season SUMMER = new Season("夏天", "烈日炎炎");
    public static final Season AUTUMN = new Season("秋天", "秋高气爽");
    public static final Season WINTER = new Season("冬天", "寒风凛凛");

    //4.其他的需求:
    public String getSeasonNamae() {
        return seasonNamae;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    @Override
    public String toString() {
        return "Season{" +
                "seasonNamae='" + seasonNamae + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}




public class SeasonTest01 {
    public static void main(String[] args) {
        Season spring = Season.SPRING;
        System.out.println(spring.getSeasonNamae() + ":" + spring.getSeasonDesc());//春天:春暖花开
    }
}

1.2 jdk5.0之后,可以使用enum关键字定义枚举类

public enum Season02 {
    //1.罗列枚举项
     SPRING ("春天", "春暖花开"),
     SUMMER ("夏天", "烈日炎炎"),
     AUTUMN ("秋天", "秋高气爽"),
     WINTER ("冬天", "寒风凛凛");

    //2.声明枚举类的属性
    private final String seasonNamae;
    private final String seasonDesc;

    //3.构造方法私有化,给成员变量赋值
    private Season02(String seasonNamae, String seasonDesc) {
        this.seasonNamae = seasonNamae;
        this.seasonDesc = seasonDesc;
    }

    //4.其他的需求:
    public String getSeasonNamae() {
        return seasonNamae;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }
}




public class SeasonTest02 {
    public static void main(String[] args) {
        Season02 spring = Season02.SPRING;
        System.out.println(spring.getSeasonNamae() + ":" + spring.getSeasonDesc());//春天:春暖花开

        //父类已经重写了toString方法
        System.out.println(spring);//SPRING

        //获取父类的名称
        String name = spring.getClass().getSuperclass().getName();
        System.out.println(name);//java.lang.Enum 

    }
}

2.注解

2.1 内置注解

 2.2 元注解

2.3 自定义注解


import java.lang.annotation.*;

public class 元注解 {

    //注解可以显示赋值, 如果没有默认值,我们就必须给注解赋值
    @MyAnnotation2()
    public void test2() {

    }

    //注解可以显示赋值, 如果没有默认值,我们就必须给注解赋值
    @MyAnnotation3("张三")//参数名为value,可以不写
    public void test3() {

    }
}

//定义一个元注解
@Target(value = {ElementType.METHOD, ElementType.TYPE})//表示注解可以用在哪些地方   方法上有效、类上有效
@Retention(value = RetentionPolicy.RUNTIME)//表示注解在什么地方还有效   runtime>class>sources
@Documented//表示是否将我们的注解生成在JAVAdoc中
@Inherited
//表示子类可以继承父类的注解
@interface MyAnnotation1 {
    
}

//自定义注解
@Target(value = {ElementType.METHOD, ElementType.TYPE})//表示注解可以用在哪些地方   方法上有效、类上有效
@Retention(value = RetentionPolicy.RUNTIME)
//表示注解在什么地方还有效   runtime>class>sources
@interface MyAnnotation2 {

    //注解的参数:参数类型+参数名();
    String name() default "";

    int age() default 0;

    int id() default -1;// 如果默认值为-1,代表不存在。

    String[] schools() default {"清华", "北大"};

}


//自定义注解
@Target(value = {ElementType.METHOD, ElementType.TYPE})//表示注解可以用在哪些地方   方法上有效、类上有效
@Retention(value = RetentionPolicy.RUNTIME)
//表示注解在什么地方还有效   runtime>class>sources
@interface MyAnnotation3 {

    //注解的参数:参数类型+参数名();
    //只有一个参数,一般用value作为参数名
    String value();

}

3.反射

3.1 Java反射机制概述

 


public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> c1 = Class.forName("Note.java基础.反射.User");
        System.out.println(c1);

        //一个类在内存中只有一个Class对象
        //一个类被加载后,类的整个结 构都会被封装在Class对象中。
        Class<?> c2 = Class.forName("Note.java基础.反射.User");
        Class<?> c3 = Class.forName("Note.java基础.反射.User");
        Class<?> c4 = Class.forName("Note.java基础.反射.User");
        Class<?> c5 = Class.forName("Note.java基础.反射.User");
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());
        System.out.println(c5.hashCode());
    }
}


3.2 理解Class类并获取Class实例

 

3.2.1自定义的类获取Class对象

public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException {

        User user = new vipUser();
        //1.根据getClass获得
        Class<? extends User> c1 = user.getClass();
        System.out.println(c1.hashCode());//356573597

        //2.根据路径获得
        Class<?> c2 = Class.forName("Note.java基础.反射.vipUser");
        System.out.println(c2.hashCode());//356573597

        //3.根据类名.class
        Class<vipUser> c3 = vipUser.class;
        System.out.println(c3.hashCode());//356573597

        //4.基本内置类的包装类类型
        Class<Integer> type = Integer.TYPE;
        System.out.println(type);//int

        //获得父类的类型
        Class<?> superclass = c1.getSuperclass();
        System.out.println(superclass);//class Note.java基础.反射.User
        
    }
}






class User {
    private String name;
    private int age;
    private int id;

    public User() {
    }

    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 int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

class vipUser extends User{

}

3.2.2 所有类型的Class对象

public class Test3 {
    public static void main(String[] args) {
        Class c1 = Object.class;
        Class C2 = Comparable.class;
        Class C3 = String[].class;
        Class c4 = int[][].class;
        Class c5 = Override.class;
        Class c6 = ElementType.class;
        Class c7 = Integer.class;
        Class c8 = void.class;
        Class c9 = Class.class;

        System.out.println(c1);//class java.lang.Object
        System.out.println(C2);//interface java.lang.Comparable
        System.out.println(C3);//class [Ljava.lang.String;
        System.out.println(c4);//class [[I
        System.out.println(c5);//interface java.lang.Override
        System.out.println(c6);//class java.lang.annotation.ElementType
        System.out.println(c7);//class java.lang.Integer
        System.out.println(c8);//void
        System.out.println(c9);//class java.lang.Class

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

        int[] arr = {1, 2,3};
        int[] arr2 = {1, 2, 3, 4, 5};
        System.out.println(arr.getClass().hashCode());//356573597
        System.out.println(arr2.getClass().hashCode());//356573597

    }
}


 


3.3 类的加载与ClassLoader

3.3.1 类的加载过程
 

 

3.3.2 什么时候发生类的初始化

3.3.3 类加载器

 

 


3.4 获取运行时类的完整结构

package Note.java基础.反射;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test04 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
        Class<?> c1 = Class.forName("Note.java基础.反射.User");

        //获取名字
        System.out.println(c1.getName());//Note.java基础.反射.User
        System.out.println(c1.getSimpleName());//User

        //获取全部publid的属性
        Field[] fields = c1.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        //找到全部属性
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
//        private java.lang.String Note.java基础.反射.User.name
//        private int Note.java基础.反射.User.age
//        private int Note.java基础.反射.User.id


        //获取指定的public属性
//        Field name1 = c1.getField("name");
//        System.out.println(name1);//报错,找不到属性名

        //获取指定属性
        Field name2 = c1.getDeclaredField("name");
        System.out.println(name2);//private java.lang.String Note.java基础.反射.User.name


        //获取本类和父类的全部public方法
        Method[] methods = c1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        //public java.lang.String Note.java基础.反射.User.getName()
        //public int Note.java基础.反射.User.getId()
        //public void Note.java基础.反射.User.setName(java.lang.String)
        //public void Note.java基础.反射.User.setAge(int)
        //public void Note.java基础.反射.User.setId(int)
        //public int Note.java基础.反射.User.getAge()
        //public final void java.lang.Object.wait() throws java.lang.InterruptedException
        //public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
        //public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
        //public boolean java.lang.Object.equals(java.lang.Object)
        //public java.lang.String java.lang.Object.toString()
        //public native int java.lang.Object.hashCode()
        //public final native java.lang.Class java.lang.Object.getClass()
        //public final native void java.lang.Object.notify()
        //public final native void java.lang.Object.notifyAll()


        //获取本类的全部方法
        Method[] declaredMethods = c1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
//        public java.lang.String Note.java基础.反射.User.getName()
//        public int Note.java基础.反射.User.getId()
//        public void Note.java基础.反射.User.setName(java.lang.String)
//        public void Note.java基础.反射.User.setAge(int)
//        public void Note.java基础.反射.User.setId(int)
//        public int Note.java基础.反射.User.getAge()


        //获得指定的public方法
        Method getName = c1.getMethod("getName", null);//这是公共的方法
        Method setName = c1.getMethod("setName", String.class);//这是公共的方法
//        Method print = c1.getMethod("print", null);//这是私有的方法,会报错
        System.out.println(getName);//public java.lang.String Note.java基础.反射.User.getName()
        System.out.println(setName);//public void Note.java基础.反射.User.setName(java.lang.String)
        

        //获得指定的方法
        Method getName1 = c1.getDeclaredMethod("getName", null);//这是公共的方法
        Method print1 = c1.getDeclaredMethod("print", null);//这是私有的方法
        System.out.println(getName1);//public java.lang.String Note.java基础.反射.User.getName()
        System.out.println(print1);//private void Note.java基础.反射.User.print()


        //获取全部public的构造方法
        Constructor<?>[] constructors = c1.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        //public Note.java基础.反射.User()
        //public Note.java基础.反射.User(java.lang.String,int,int)


        //获取全部的构造方法
        Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        //public Note.java基础.反射.User()
        //public Note.java基础.反射.User(java.lang.String,int,int)


        //获取指定构造方法
        Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println(declaredConstructor);
        //public Note.java基础.反射.User(java.lang.String,int,int)


    }
}


3.5 调用运行时类的指定结构

3.5.1 通过反射创建对象、调方法、造作属性

 

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//通过反射动态创建对象
public class Test05 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<?> c1 = Class.forName("Note.java基础.反射.User");

        //构造一个对象
        User user = (User) c1.newInstance();//必要要有空参构造!!!!!!
        System.out.println(user);

        //通过构造器创建对象
        Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        User user2 = (User) declaredConstructor.newInstance("张三", 20, 20);
        System.out.println(user2);

        //通过反射调方法
        User user3 = (User) c1.newInstance();
        Method setName = c1.getDeclaredMethod("setName", String.class);
        setName.invoke(user3, "张三");
        System.out.println(user3.getName());

        //通过反射操作属性
        User user4 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        name.setAccessible(true);//私有的属性不能直接访问,要先取消安全检测!!!!!!!!!
        name.set(user4, "李四");
        System.out.println(user4.getName());


    }
}

3.5.2 性能测试

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//分析性能
public class Test06 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        test01();//普通方式:3ms
        test02();//反射方式:2138ms
        test03();//关闭检测:1032ms
    }

    static void test01() {
        //普通方式
        User user = new User();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }
        long end = System.currentTimeMillis();
        System.out.println("普通方式:" + (end - start) + "ms");
    }

    static void test02() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //反射方式
        User user = new User();
        Class<? extends User> c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user, null);
        }
        long end = System.currentTimeMillis();
        System.out.println("反射方式:" + (end - start) + "ms");
    }


    static void test03() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //反射方式,
        User user = new User();
        Class<? extends User> c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user, null);
        }
        long end = System.currentTimeMillis();
        System.out.println("关闭检测:" + (end - start) + "ms");
    }
}

3.5.3获取泛型信息

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

//通过反射获取泛型
public class Test07 {
    public static void main(String[] args) throws NoSuchMethodException {
        
        Class<Test07> test07Class = Test07.class;
        
        //1.参数的泛型
        Method test01 = test07Class.getDeclaredMethod("test01", Map.class, List.class);
        Type[] genericParameterTypes = test01.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println(genericParameterType);
        }
        //java.util.Map<java.lang.String, Note.java基础.反射.User>
        //java.util.List<Note.java基础.反射.User>

        //2.返回值的泛型
        Method test02 = test07Class.getDeclaredMethod("test02", null);
        Type genericReturnType = test02.getGenericReturnType();
        System.out.println(genericReturnType);//java.util.Map<java.lang.String, Note.java基础.反射.User>


    }

    public static void test01(Map<String,User> map, List<User> list){
        System.out.println("test01");
    }

    public static Map<String,User> test02(){
        System.out.println("test02");
        return null;
    }
}



3.6练习反射操作注解


import java.lang.annotation.*;

public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class<?> c1 = Class.forName("Note.java基础.反射.Student");

        //通过反射获取注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);//@Note.java基础.反射.Table(value=db_student)
        }

        //获得注解的value的值
        Table annotationTable = c1.getAnnotation(Table.class);
        String value = annotationTable.value();
        System.out.println(value);//db_student

        //获取指定属性的注解的值
        java.lang.reflect.Field id = c1.getDeclaredField("id");//通过属性名获取属性对象
        Field annotationId = id.getAnnotation(Field.class);//通过注解.calss获取注解对象
        System.out.println(annotationId.columnName());//db_id
        System.out.println(annotationId.type());//int
        System.out.println(annotationId.length());//10

        java.lang.reflect.Field name = c1.getDeclaredField("name");//通过属性名获取属性对象
        Field annotationName = name.getAnnotation(Field.class);//通过注解.calss获取注解对象
        System.out.println(annotationName.columnName());//db_name
        System.out.println(annotationName.type());//varchar
        System.out.println(annotationName.length());//3

        java.lang.reflect.Field age = c1.getDeclaredField("age");//通过属性名获取属性对象
        Field annotationAge = age.getAnnotation(Field.class);//通过注解.calss获取注解对象
        System.out.println(annotationAge.columnName());//db_age
        System.out.println(annotationAge.type());//int
        System.out.println(annotationAge.length());//10
        
    }
}

@Table("db_student")
//数据库中有db_student的表
class Student {
    @Field(columnName = "db_id", type = "int", length = 10)
    private int id;
    @Field(columnName = "db_name", type = "varchar", length = 3)
    private String name;
    @Field(columnName = "db_age", type = "int", length = 10)
    private int age;

    public Student() {
    }

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

    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;
    }

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

//类名的注解,这个类映射到哪个数据库表
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table {
    String value();
}

//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Field {
    String columnName();//列名

    String type();//数据类型

    int length();//数据长度
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值