狂神-注解和反射

1、注解

是注释和程序进行解析的内容

元注解

常用的内容

public class Test1 {
    @MyAnnotation1(age=18,id=520)
    public  void test1(String[] args) {

    }
    @MyAnnotation2()
    public  void test3(String[] args) {

    }
}

//自定义一个注解
//Target:指的是作用的范围,在哪些地方生效
@Target(value ={ElementType.METHOD,ElementType.TYPE} )
//Retentions是运行是生效
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation1{
    //注解的参数:参数类型+参数名();
    String name() default "大美女";
    int age();
    int id () default -1;//如果默认值是-1表示不存在
    String[] schools() default {"清华","北大"};

}
//另外一种情况是,只有value的时候,是不用写参数名称的
@interface MyAnnotation2{
    String value() default "";
}

 2、反射 

一个类在内存中只有一个class

一个类被加载后,类的整个结构都封装在Class 对象中。

主要的API是:Class(代表一个类)、Method(方法)、Field(成员变量)、Construction(构造函数)

2.1、Class 类创建方式  

打印结果是一样,说明只能是创建一个Class 对象

public class test1 {

    public static void main(String[] args) throws ClassNotFoundException {
        Person person= new Teacher();
        System.out.println("This is "+person.name);
        //方式1  获取Class对象的方式
        Class p1 = person.getClass();
        System.out.println(p1.hashCode());
        //方式2
        Class p2 = Class.forName("com.kuang.reflection.Teacher");
        System.out.println(p2.hashCode());
        //方式3          推荐方式
        Class<Teacher> p3 = Teacher.class;
        System.out.println(p3.hashCode());
    }
}

class Person{
    int id;
    String name;

    public Person() {
    }

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

    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 Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
}
class Student extends Person{
    public Student() {
        this.name="学生";
    }
}
class Teacher extends Person{
    public Teacher() {
        this.name="老师";
    }
}

2.1.1所有类型的Class对象

public class Test2 {
    public static void main(String[] args) {
        //类
        Class c1 = Object.class;
        //void
        Class c2 = Void.class;
        //一维数组
        Class c3 = int[].class;
        //二维数组
        Class c4 = int[][].class;
        //包装类型
        Class c5 = Integer.class;
        //注解
        Class c6 = Override.class;
        //枚举
        Class c7 = ElementType.class;
        //接口
        Class c8 = Comparable.class;
        //class
        Class c9 = Class.class;

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);
        int [] a=new int[10];
        int [] b=new int[100];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());
        //只要元素类型和维度是一致的,就是同一个class
    }
}

  打印的结果基本都是class 和interface

2.2、类加载过程

分为3步:加载、链接、初始化

 

public class Test3 {
    public static void main(String[] args) {
        A a=new A();
        System.out.println(A.m);
    }

    /**
     * 1、加载到内存,会产生一个 类对应的class对象
     * 2、链接 (1、验证2、准备3、解析)结束后生成 m=0;
     * 3、初始化
     *  <clinit> (){
     *      执行静态代码块、静态方法、静态变量合并
     *       System.out.println("静态代码块");
     *       int m=30;
     *       static  int m=100;
     *  }
     *  m=100
     *  */
}

class A{
    static {
        System.out.println("静态代码块");
        int m=30;
    }
    static  int m=100;

    public A() {
        System.out.println("无参构造函数");
    }
}

 

 

 

 

 

 

 

 2.2.1、分析类初始化

有一个双亲委派机制

会先找系统加载器--->扩展类加载器--->跟加载器,如果在上层找到了,就会执行上层找到的类

public class Test7 {

    public static void main(String[] args) {
        //系统类的加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);
        //系统加载类的父加载器--->扩展类加载器
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);
        //扩展类加载器的父类--->根加载器(C/C++)
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);
        //测试当前类的加载器是哪个
        ClassLoader classLoader = Test7.class.getClassLoader();
        System.out.println(classLoader);

        //jdk下的类
        classLoader = Object.class.getClassLoader();
        System.out.println(classLoader);
    }

}

  

 2.3、通过反射操作属性、方法、构造器等

public class Test8 {

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class c1 = Person.class;
        Object p1 = c1.newInstance();
        System.out.println(p1);
        //通过反射,走的是无参构造

        //走有参构造
        Constructor p2 = c1.getDeclaredConstructor( int.class, String.class);
        Person pp = (Person)p2.newInstance( 001, "小白兔");
        System.out.println(pp);

        //通过反射调用普通方法
        Method setName = c1.getDeclaredMethod("setName",String.class);
        //invoke:激活的意思
        //(对象,方法的值)
        setName.invoke(pp, "小月月");
        System.out.println(pp.getName());

        //通过反射操作属性
        Field name = c1.getDeclaredField("name");
        //打破封装,提高反射效率
        name.setAccessible(true);
        name.set(pp,"哈哈哈~~~");
        System.out.println(pp.getName());
    }
}

  2.3.1、验证一下access 的效率

public class Test9 {

    public static void test1() {
        Person person = new Person();
        long starTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            person.getName();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("new 方式创建对象耗时" + (endTime - starTime) + "ms");
    }
    public static void test2() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Class<Person> personClass = Person.class;
        Person person = personClass.newInstance();
        Method getName = personClass.getDeclaredMethod("getName", null);
        long starTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(person, null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("反射方式创建对象耗时" + (endTime - starTime) + "ms");
    }
    public static void test3() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Class<Person> personClass = Person.class;
        Person person = personClass.newInstance();
        Method getName = personClass.getDeclaredMethod("getName", null);
        getName.setAccessible(true);
        long starTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(person, null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Accessible方式创建对象耗时" + (endTime - starTime) + "ms");
    }
    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        test1();
        test2();
        test3();
    }
}

  2.4、通过反射获取泛型

public class Test10 {
    
    public static void test01(Map<String,Student> map, List<Person> list){
        System.out.println("test01");
    }
    public static  Map<String,Student>  test02(){
        System.out.println("test01");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method method = Test10.class.getDeclaredMethod("test01", Map.class, List.class);
     //泛型参数类型 Type[] genericParameterTypes = method.getGenericParameterTypes(); for (Type genericParameterType : genericParameterTypes) { System.out.println(genericParameterType); if (genericParameterType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } System.out.println("8888888888"); method = Test10.class.getDeclaredMethod("test02");
    //返回值类型 Type genericReturnType = method.getGenericReturnType(); if (genericReturnType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } }

  2.5、通过反射获取注

public class Test11 {
    public static void main(String[] args) throws NoSuchFieldException {
        Class<Dog> c1 = Dog.class;
        //通过反射获取注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //获取注解的value值
        DogTable dogTable = c1.getDeclaredAnnotation(DogTable.class);
        System.out.println(dogTable.value());
        //获得类指定的注解
        Field name = c1.getDeclaredField("name");
        DogFile annotation = name.getAnnotation(DogFile.class);
        System.out.println(annotation.length());
        System.out.println(annotation.name());
        System.out.println(annotation.type());
    }
}

//ORM:对象关系映射,在数据库有一个表是叫Dog
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface DogTable{
    //表名
    String value();
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface DogFile{
    //字段名
    String name();
    int length();
    String type();
}

@DogTable("db_dog")
class Dog {
    @DogFile(name="db_name",length=10,type="varchar")
    private  String name;
    @DogFile(name="db_age",length=10,type="int")
    private  int age;
    @DogFile(name="db_color",length=10,type="varchar")
    private  String color;

    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 String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Dog() {
    }

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

  

 

 

posted @ 2021-11-09 22:07  白小纯~  阅读(179)  评论(0)    收藏  举报