注解和反射

注解和反射

注解

注解和注释的区别

注解 annotation写在程序之中,程序可以识别,做出相应的动作处理,具有检查和约束程序的作用

注释 comment 写在程序之中,供人参考,提示使用,程序会自动忽略

注解在JDK5开始引入

常见注解

@Override 重写一个方法

@Deprecated 不推荐使用

@SuppressWarnings("all") 镇压警告

元注解

元注解就是可以负责注解其他的注解

@Target 描述注解的使用范围

@Retention 表示在什么级别保存该注解信息(Source < Class < Runtime)

@Document 该注解被包含在javadoc

@Inherited 说明子类可以继承父类中的注解

自定义注解

@MyAnnotation(value = "User MyAnnotation", university = "家里蹲大学", age = 666)
public class User {
    @MyAnnotation(name = "main Method", age = 18, id = 1, university = "复旦大学", value = "main MyAnnotation")
    public static void main(String[] args) throws NoSuchMethodException {
        Class<User> userClass = User.class;
        System.out.println("==============method===============");
        Method main = userClass.getMethod("main", String[].class);
        if (main.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation annotation = main.getAnnotation(MyAnnotation.class);
            System.out.println(annotation.age());
            System.out.println(annotation.id());
            System.out.println(Arrays.toString(annotation.university()));
            System.out.println(annotation.name());
            System.out.println(annotation.value());
        }
        System.out.println("==============class===============");
        if (userClass.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation annotation = userClass.getAnnotation(MyAnnotation.class);
            System.out.println(annotation.age());
            System.out.println(annotation.id());
            System.out.println(Arrays.toString(annotation.university()));
            System.out.println(annotation.name());
            System.out.println(annotation.value());
        }
    }
}

@Target(value = {ElementType.METHOD, ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation {
    String name() default "name";

    int age() default 0;

    // -1 代表不存在
    int id() default -1;

    String[] university() default {"清华大学", "北京大学"};

    String value();
}

运行结果
在这里插入图片描述

注解级别

@Table("Anno类")
public class Anno {
    @Feild("用户名")
    private String username;
    @Method("main函数")
    public static void main(String[] args) {}
}

@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
@interface Table{
    String value();
}

@Target(value = ElementType.FIELD)
@Retention(value = RetentionPolicy.RUNTIME)
@interface Feild{
    String value();
}

@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@interface Method{
    String value();
}

查看ElementType枚举类的源码如下

package java.lang.annotation;
public enum ElementType{
    TYPE,
    FIELD,
    METHOD,
    PARAMETER,
    CONSTRUCTOR,
    LOCAL_VARIABLE,
    ANNOTATION_TYPE,
    PACKAGE,
    TYPE_PARAMETER,
    TYPE_USE,
    MODULE;

    private ElementType() {
    }
}

这个枚举类实现了单例模式,构造器私有

属性

TYPE
public static final ElementType TYPE
类,接口(包括注释类型)或枚举声明

FIELD
public static final ElementType FIELD
字段声明(包括枚举常数)

METHOD
public static final ElementType METHOD
方法声明

PARAMETER
public static final ElementType PARAMETER
正式参数声明

CONSTRUCTOR
public static final ElementType CONSTRUCTOR
构造函数声明

LOCAL_VARIABLE
public static final ElementType LOCAL_VARIABLE
局部变量声明

ANNOTATION_TYPE
public static final ElementType ANNOTATION_TYPE
注解类型声明

PACKAGE
public static final ElementType PACKAGE
包装声明

TYPE_PARAMETER
public static final ElementType TYPE_PARAMETER
键入参数声明

TYPE_USE
public static final ElementType TYPE_USE
使用类型

MODULE
public static final ElementType MODULE
模块声明,jdk11具有的

反射

反射 reflection,一个类在内存中只存在一个class对象,一个类被加载之后,类的整个结构都会封装在Class对象中

public class ReflectionDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.mao.pojo.User");
        Class<?> bClass = Class.forName("com.mao.pojo.User");
        Class<?> cClass = Class.forName("com.mao.pojo.User");

        System.out.println(aClass.hashCode());
        System.out.println(bClass.hashCode());
        System.out.println(cClass.hashCode());
    }
}

class User{
    private String username;
    private String password;
}

获取class对象

    public static void main(String[] args) throws ClassNotFoundException {
        User user = new User();
        System.out.println(user);

        // 对象获取
        Class aClass = user.getClass();
        System.out.println(aClass.hashCode());

        // forName 获取
        Class bClass = Class.forName("com.mao.pojo.User");
        System.out.println(bClass.hashCode());

        // 类.class
        Class<User> cClass = User.class;
        System.out.println(cClass.hashCode());

        // 基本数据类型的包装类获得
        Class<Integer> type = Integer.TYPE;
        System.out.println(type);

        System.out.println(type.getSuperclass());
        System.out.println(aClass.getSuperclass());
    }

所有类型的Class对象

    public static void main(String[] args) throws ClassNotFoundException {
        System.out.println(Object.class);
        System.out.println(Comparable.class);
        System.out.println(String[].class);
        System.out.println(int[][].class);
        System.out.println(Override.class);
        System.out.println(Integer.class);
        System.out.println(void.class);
        System.out.println(Class.class);
        System.out.println(new int[10].getClass().hashCode());
        System.out.println(new int[100].getClass().hashCode());
    }

结果是

class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.Integer
void
class java.lang.Class
750044075
750044075

查看类加载器

    public static void main(String[] args) throws ClassNotFoundException {
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);

        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);

        ClassLoader classLoader = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader);
    }

jdk.internal.loader.ClassLoaders A p p C l a s s L o a d e r @ 2437 c 6 d c j d k . i n t e r n a l . l o a d e r . C l a s s L o a d e r s AppClassLoader@2437c6dc jdk.internal.loader.ClassLoaders AppClassLoader@2437c6dcjdk.internal.loader.ClassLoadersPlatformClassLoader@2cb4c3ab
null
null

在这里插入图片描述
获取java运行放入环境在这里插入图片描述

获取类运行时的结构

public class ReflectionDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Class className = Class.forName("com.mao.pojo.User");
        System.out.println(className.getClass());
        System.out.println(className.getSimpleName());
        System.out.println("=============================");
        User user = new User();
        className = user.getClass();
        System.out.println(className.getClass());
        System.out.println(className.getSimpleName());
        System.out.println(className.getField("username"));
        System.out.println(className.getField("password"));
    }
}

class User{
    public String username;
    private String password;

}

在这里插入图片描述
获取构造器

        Class className = Class.forName("com.mao.pojo.User");
        Constructor[] constructors = className.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        constructors = className.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

在这里插入图片描述

通过构造器创建对象

        Class classObject = Class.forName("com.mao.pojo.User");
        //  newInstance() 需要无参构造器,且防蚊权限足够
        User user = (User) classObject.newInstance();
        System.out.println(user);

        Constructor constructor = classObject.getDeclaredConstructor(String.class,String.class);
        User root = (User)constructor.newInstance("root", "123456");
        System.out.println(root);

在这里插入图片描述

反射获取到类对象,创建实例,获取到方法的set方法,通过invoke激活,对对对象设置值

public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException {
        Class classObject = Class.forName("com.mao.pojo.User");
        User user = (User) classObject.newInstance();
        Method setUsername = classObject.getDeclaredMethod("setUsername", String.class);
        setUsername.invoke(user,"root");
        System.out.println(user.getUsername());
    }

反射将私有属性进行访问

        Class classObject = Class.forName("com.mao.pojo.User");
        User user = (User) classObject.newInstance();
        Field username = classObject.getDeclaredField("username");
        // 破解 private,取消安全检测
        username.setAccessible(true);

        username.set(user,"admin");
        System.out.println(user.getUsername());

在这里插入图片描述

对比正常使用创建对象,反射创建对象,设置可见性的方式对比性能,结果发现new方式创建对象的方式最快,反射创建对象的时间最长,关闭检查,性能可提高一倍

public class ReflectionDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException {
        // 普通方式
        User user = new User();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            user.getUsername();
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        // 反射获取方法
        Class aClass = Class.forName("com.mao.pojo.User");
        Method getUsername = aClass.getDeclaredMethod("getUsername", null);

        long start1 = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getUsername.invoke(user,null);
        }
        long end1 = System.currentTimeMillis();
        System.out.println(end1 - start1);


        // 反射获取方法,关闭检查
        Class bClass = Class.forName("com.mao.pojo.User");
        Method getUsername1 = bClass.getDeclaredMethod("getUsername", null);
        getUsername1.setAccessible(true);

        long start2 = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getUsername1.invoke(user,null);
        }
        long end2 = System.currentTimeMillis();
        System.out.println(end2 - start2);
    }
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class User{
    private String username;
    private String password;

}

在这里插入图片描述

  • 14
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值