java 基础注解和反射(完结)

本贴最后更新于 1356 天前,其中的信息可能已经时移世改

四个元注解

image.png

package net.yscxy.annoction;

import java.lang.annotation.*;

/**
 * @Author WangFuKun
 * @create 2020/12/4 20:20
 */
//测试元注解

public class Test02 {
    @MyAnotation
    public void test() {

    }
}

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

}

Target 表示我们的注解可以用在哪些地方
Retention 表示我们的注解在什么时候还有效 runtime>class>source
Documented 表示是否将我们的注解生成在 javadoc 中
Inherited 子类可以继承父类

如何自定义注解

image.png

package net.yscxy.annoction;

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;

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

/**
 * @Author WangFuKun
 * @create 2020/12/4 21:30
 */
//自定义注解
public class Test03 {
    @Test
    @MyAnnotation2(name = "wfk", age = 10)
    public void test() {

    }
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
    //注解的参数:参数类型+参数名();
    String name() default "";

    int age();

    int id() default -1;//如果默认值为-1,代表不存在,如果找不到就返回-1

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

反射机制

静态语言 VS 动态语言

image.png

Java Reflection

image.png

image.png

获取 Class 类的实例的几种方案

image.png

package net.yscxy.reflection;

/**
 * @Author 野生程序员 http://yscxy.net/
 * @create 2020/12/5 10:29
 */
public class Test03 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("这个人是->" + person.name);
        //方式一:通过对象获得
        Class c1 = person.getClass();
        System.out.println(c1);
        //方式二:forname获得
        Class c2 = Class.forName("net.yscxy.reflection.Student");
        System.out.println(c2);
        //方式三:通过类名.class获得
        Class c3 = Student.class;
        System.out.println(c3);
        //方式四:基本内置类型的包装类都有一个Type属性
        Class c4 = Integer.TYPE;
        System.out.println(c4);
        //获得父类类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);
    }
}

class Person {
    String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

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

class Student extends Person {
    public Student() {
        this.name = "学生";
    }


}

class Teacher extends Person {
    public Teacher() {
        this.name = "老师";
    }
}

代码二

package net.yscxy.reflection;

import java.lang.annotation.ElementType;

/**
 * @Author 野生程序员 http://yscxy.net/
 * @create 2020/12/5 10:46
 */
//所有类的class
public class Test04 {
    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;//void
        Class c9 = Class.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);
    }
}
什么时候会发生类的初始化

image.png

package net.yscxy.reflection;

/**
 * @Author 野生程序员 http://yscxy.net/
 * @create 2020/12/5 11:10
 */
public class Test06 {
    static {
        System.out.println("main类被加载...");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        //1.主动引用
        //Son son = new Son();
        //反射也会产生主动引用引用
        //Class.forName("net.yscxy.reflection.Son");
        //不会产生类的引用的方法
        //System.out.println(Son.b);
        //Son[] arr = new Son[5];
        //System.out.println(Son.M);
    }
}

class Father {
    static int b = 2;

    static {
        System.out.println("父类被加载...");
    }
}

class Son extends Father {
    static {
        System.out.println("子类被加载...");
    }

    static int m = 100;
    static final int M = 1;
}
类加载器的作用

image.png

获取类的方法、字段、构造器、等等
package net.yscxy.reflection;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @Author 野生程序员 http://yscxy.net/
 * @create 2020/12/5 15:49
 */
public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("net.yscxy.reflection.User");
        //获得类的名字
        System.out.println(c1.getName());
        System.out.println(c1.getSimpleName());
        //获得类的属性
        Field[] fields = c1.getFields();//只能找到public属性
        for (int i = 0; i < fields.length; i++) {
            System.out.println(fields[i]);
        }
        Field name = c1.getDeclaredField("name");
        System.out.println(name);
        //获得类的方法
        System.out.println("=======================获得类的方法=========================");
        Arrays.asList(c1.getMethods()).forEach(System.out::println);//获得本类以及父类的全部public方法
        System.out.println("=======================获得本类的所有方法=========================");
        Arrays.asList(c1.getDeclaredMethods()).forEach(System.out::println);//获得本类的所有方法
        //获得指定方法
        System.out.println("获得指定方法");
        Method getName = c1.getMethod("getName", null);
        Method getAge = c1.getMethod("getAge", null);
        System.out.println(getName);
        System.out.println(getAge);
        System.out.println("获得指定的构造器");
        Constructor[] constructors = c1.getConstructors();
        Arrays.asList(constructors).forEach(System.out::println);
        System.out.println("+++++++++++");
        Arrays.asList(c1.getDeclaredConstructors()).forEach(System.out::println);
        System.out.println("获得指定的构造器");
        Constructor declaredConstructor = c1.getDeclaredConstructor(int.class, String.class, int.class);
        System.out.println("指定:" + declaredConstructor);
    }
}
通过反射动态创建对象

image.png

package net.yscxy.reflection;

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

/**
 * @Author 野生程序员 http://yscxy.net/
 * @create 2020/12/6 8:43
 */
//通过反射动态创建对象
public class Test09 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<?> c1 = Class.forName("net.yscxy.reflection.User");
        //构造对象
        User user = (User) c1.newInstance();
        System.out.println(user);
        //通过构造器创建对象
        Constructor<?> declaredConstructor = c1.getDeclaredConstructor(int.class, String.class, int.class);
        User user13 = (User) declaredConstructor.newInstance(1, "测试", 1);
        System.out.println(user13);
        //通过反射获取一个方法,invoke激活的意思
        User user3 = (User) c1.newInstance();
        Method setName = c1.getDeclaredMethod("setName", String.class);
        setName.invoke(user3, "野生程序员");
        System.out.println(user3);
        //通过反射操作属性
        User user4 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        //设置属性是否可以被访问,也就是取消他的安全监测,不能直接访问私有属性,只有关掉之后才能访问
        name.setAccessible(true);
        name.set(user4, "野生程序员2");
        System.out.println(user4);

    }
}
三种方式的额性能检测
package net.yscxy.reflection;

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

/**
 * @Author 野生程序员 http://yscxy.net/
 * @create 2020/12/7 16:07
 */
//分析反射性能问题
public class Test10 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        test01();
        test02();
        test3();
    }

    //普通方式调用
    public static void test01() {
        User user = new User();
        long starTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通方式耗费时间->" + (endTime - starTime));
    }

    //反射方式调用
    public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        long starTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user, null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("反射方式耗费时间->" + (endTime - starTime));
    }

    //反射方式调用 并且关闭安全检测
    public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);
        long starTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user, null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("反射并且关闭安全检查方式耗费时间->" + (endTime - starTime));
    }
}

运行结果

普通方式耗费时间->5
反射方式耗费时间->4928
反射并且关闭安全检查方式耗费时间->2171

通过反射操作泛型

image.png

package net.yscxy.reflection;

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

/**
 * @Author 野生程序员 http://yscxy.net/
 * @create 2020/12/7 16:24
 */
//通过反射获取泛型
public class Test11 {
    public void test01(Map<String, User> map, List<User> list) {
        System.out.println("test01");
    }

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

    public static void main(String[] args) throws NoSuchMethodException {
        //获取参数的泛型类型
        Method method = Test11.class.getMethod("test01", Map.class, List.class);
        Type[] genericExceptionTypes = method.getGenericParameterTypes();
        for (Type ge : genericExceptionTypes) {
            System.out.println(ge);
            //instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例
            if (ge instanceof ParameterizedType) {
                System.out.println("开始打印...");
                Type[] actualTypeArguments = ((ParameterizedType) ge).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        }
        System.out.println("获取返回值的泛型的参数类型...");
        method = Test11.class.getMethod("test02", null);
        Type genericReturnType = method.getGenericReturnType();
        System.out.println(genericReturnType);
        if (genericReturnType instanceof ParameterizedType) {
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }
    }
}

运行结果

java.util.Map<java.lang.String, net.yscxy.reflection.User>
开始打印...
class java.lang.String
class net.yscxy.reflection.User
java.util.List<net.yscxy.reflection.User>
开始打印...
class net.yscxy.reflection.User
获取返回值的泛型的参数类型...
java.util.Map<java.lang.String, net.yscxy.reflection.User>
class java.lang.String
class net.yscxy.reflection.User

反射操作注解

了解一下什么叫 ORM

image.png

package net.yscxy.reflection;

import java.lang.annotation.*;
import java.lang.reflect.Field;

/**
 * @Author 野生程序员 http://yscxy.net/
 * @create 2020/12/7 16:59
 */
public class Test12 {
    public static void main(String[] args) throws NoSuchFieldException {
        Class c1 = Student2.class;
        //通过反射获取注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation a : annotations) {
            System.out.println(a);
        }
        //获取注解的value的值
        TableY tableY = (TableY) c1.getAnnotation(TableY.class);
        System.out.println(tableY.value());
        //获得类指定的注解
        Field f = c1.getDeclaredField("name");
        FiledY annotation = f.getAnnotation(FiledY.class);
        System.out.println(annotation.columnName());
        System.out.println(annotation.type());
        System.out.println(annotation.length());

    }
}

//数据
@TableY("du_student")
class Student2 {
    @FiledY(columnName = "db_id", type = "int", length = 10)
    private int id;
    @FiledY(columnName = "db_age", type = "int", length = 10)
    private int age;
    @FiledY(columnName = "db_name", type = "varchar", length = 3)
    private String name;

    public Student2() {
    }

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

    public int getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

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

//类名注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface TableY {
    String value();
}

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

    String type();

    int length();
}

运行结果

@net.yscxy.reflection.TableY(value=du_student)
du_student
db_name
carchar
3

  • 反射和注解
    1 引用
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3169 引用 • 8208 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...