反射与注解

本文详细介绍了Java中的注解及其元注解,包括@Override、@Deprecated、@SuppressWarnings等,并展示了如何自定义注解。此外,还深入探讨了反射的概念,如何获取Class对象,以及利用反射操作类、方法、属性。同时,文中还涵盖了泛型信息的获取以及通过反射获取和使用注解。
摘要由CSDN通过智能技术生成

注解

注解有什么作用

注解可以被编译器和程序读取

注解可以对程序本身做一些解释

基本的注解

public class A extends Object {
    @Override//重写注解
    public String toString() {
        return super.toString();
    }

    @Deprecated//不建议使用该方法注解
    public void s() {

    }

    @SuppressWarnings("all")//可以用来压制编译器警告
    public void sdawd() {

    }
}

元注解

元注解一般用在定义注解上

java有4个基本的元注解

//自定义一个注解
@Target({ElementType.METHOD, ElementType.FIELD})//表示可以在方法,和属性上用
@Retention(RetentionPolicy.RUNTIME)//表示在运行时注解生效
@Documented //表示是否将该注解生成到javadoc中
@Inherited   //子类可以继承父类的注解
@interface MyAnn {
    //注解可以携带参数
    String value() default "llk";//表示默认有值
}

public class A {
    @MyAnn
    private int id;

    @MyAnn
    public void t() {

    }
}

反射

什么是反射

反射可以在程序运行时获取程序的一些属性和方法

一个类只有一个反射对象

反射获取对象Class

public class Doc {
}


class User extends Doc {

    private int id;
    public String name;

    static {
        System.out.println("静态资源被反射触发了");
    }

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

        Class<?> user1 = Class.forName("User");//方法1通过包名
        Class<?> user2 = user.getClass();//方法2通过对象获取
        Class<?> user3 = User.class;//方法3通过类名获取
        Class<?> user4 = Class.forName("User");
        //每个类会创建一个单例模式的反射对象
        System.out.println(user1.hashCode() == user3.hashCode() && user2.equals(user4));//true

        Class<?> i = Integer.TYPE;//方法4,缺点只有特定的类型才能这样使用


        //获取父类的类型class
        Class<?> superclass = user1.getSuperclass();
        System.out.println(superclass);


    }
}

哪些类可以有Class对象

在这里插入图片描述

反射会获取class对象会强制加载其内部静态资源

类加载器

class User extends Doc {

    public static void main(String[] args) throws ClassNotFoundException {
        //获取系统类加载器
        ClassLoader classLoader = User.class.getClassLoader();
        System.out.println(classLoader);
        //获取扩展类加载器
        ClassLoader parent = classLoader.getParent();
        System.out.println(parent);
        //获取根加载器
        ClassLoader loader = parent.getParent();
        System.out.println(loader);


        //获取系统加载器可以加载的路径
        String property = System.getProperty("java.class.path");
        for (String s : property.split(":")) {
            System.out.println(s);
        }
        /*
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/charsets.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/deploy.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/cldrdata.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/dnsns.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/jaccess.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/jfxrt.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/localedata.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/nashorn.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/sunec.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/zipfs.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/javaws.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jce.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jfr.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jfxswt.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jsse.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/management-agent.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/plugin.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/resources.jar
        /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/rt.jar
        /Users/pjy/code/JAVAWEB/mytest/out/production/mytest
        * */

    }
}

获取类的完整信息

class User extends Doc {
    private int id;
    public String name;

    public User() {
    }

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

    public User(int id) {
        this.id = id;
    }

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

    private void fx() {
        System.out.println("xxxxxxx@qq.com");
    }

    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 static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        Class<?> user = Class.forName("User");
        System.out.println(user.getName());//获取完整类名
        System.out.println(user.getSimpleName());//获取类的名字


        //获取公开属性
        Field[] fields = user.getFields();
        //获取本类所有属性
        Field[] declaredFields = user.getDeclaredFields();


        //获取共有方法
        Method[] methods = user.getMethods();
        //获取本类的所有方法
        Method[] declaredMethods = user.getDeclaredMethods();

        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        //获取共有指定方法 参数方法名称,和方法参数class
        Method setId = user.getMethod("setId", int.class);
        System.out.println(setId);
        //获取本类任意指定方法
        Method fx = user.getDeclaredMethod("fx");
        System.out.println(fx);

        System.out.println("----------------------------------------");
        //获取指定的共有构造器
        Constructor<?> constructor = user.getConstructor(int.class);
        System.out.println(constructor);
        //获取任意本类的构造器
        Constructor<?> declaredConstructor = user.getDeclaredConstructor(String.class);
        System.out.println(declaredConstructor);
        //获取全部共有构造器
        Constructor<?>[] constructors = user.getConstructors();
        //获取本类所有构造器
        Constructor<?>[] declaredConstructors = user.getDeclaredConstructors();
    }
}


通过反射操控对象

class User extends Doc {
    private int id;
    public String name;


    public User() {
    }

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

    public User(int id) {
        this.id = id;
    }

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

    private void fx() {
        System.out.println("xxxxxxx@qq.com");
    }

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

    private String updateName(String name) {
        return this.name = name;
    }

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {

        //通过反射创建对象
        //第一种方法
        Class<User> userClass = User.class;
        //此方法必须在拥有无惨构造切能被访问时才能使用
        User user = userClass.newInstance();

        //第二种方法
        Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class);
        //传入构造器所需要的参数
        User user2 = declaredConstructor.newInstance("李大侠");


        //通过反射调用对象方法
        Method declaredMethod = userClass.getDeclaredMethod("updateName", String.class);
        //对象+方法参数  返回值是被调用函数的返回值
        Object re = declaredMethod.invoke(user2, "肥猫");

        System.out.println(re);


        //通过反射操控属性

        User user3 = new User();
        Field id = userClass.getDeclaredField("id");
        //有可能报错访问权限不足 使用一下方法解决,true是可访问,false不能访问
        id.setAccessible(true);
        id.set(user3, 857);

        System.out.println(user3.getId());

    }
}

反射获取泛型

class User extends Doc {

    public void dec(Map<String, Object> map, Collection<Integer> col) {

    }

    public Map<String, String> doc() {
        return new HashMap<>();
    }

    public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        //获取参数信息
        Class<User> userClass = User.class;
        Method ft = userClass.getDeclaredMethod("dec", Map.class, Collection.class);
        Type[] genericParameterTypes = ft.getGenericParameterTypes();//获取方法参数
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println(genericParameterType);
            //判断是否是一个参数化类型
            if (genericParameterType instanceof ParameterizedType) {
                //获取泛型实际类型信息
                Type[] types = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type type : types) {
                    System.out.println(type);//打印泛型实际类型
                }
            }
        }

        System.out.println("--------------------------------");
        //获取返回信息
        Method doc = userClass.getDeclaredMethod("doc");
        Type genericReturnType = doc.getGenericReturnType();//获取返回值信息
        System.out.println(genericReturnType);
        //判断是否是一个参数化类型
        if (genericReturnType instanceof ParameterizedType) {
            //获取泛型实际类型信息
            Type[] types = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type type : types) {
                System.out.println(type);//打印泛型实际类型
            }
        }

    }
}

获取注解信息

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

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

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

    String type();

    int length();
}

@ClassAnnotation("学生类")
public class Student {
    @FieldAnnotation(name = "学号", type = "int", length = 20)
    private int id;
    @FieldAnnotation(name = "姓名", type = "String", length = 50)
    private String name;
    @FieldAnnotation(name = "年龄", type = "int", length = 3)
    private int age;
    @FieldAnnotation(name = "姓别", type = "bool", length = 1)
    private boolean sex;

    public static void main(String[] args) throws NoSuchFieldException {
        Class<Student> studentClass = Student.class;

        //获取类上的注解
        Annotation[] declaredAnnotations = studentClass.getAnnotations();
        for (Annotation declaredAnnotation : declaredAnnotations) {
            System.out.println(declaredAnnotation);
        }

        //获取注解的值
        ClassAnnotation classAnnotation = studentClass.getAnnotation(ClassAnnotation.class);
        System.out.println(classAnnotation.value());

        System.out.println("------------------------");
        //获取指定类的注解
        Field age = studentClass.getDeclaredField("age");
        age.setAccessible(true);
        FieldAnnotation fieldAnnotation = age.getAnnotation(FieldAnnotation.class);
        System.out.println(fieldAnnotation.name());
        System.out.println(fieldAnnotation.type());
        System.out.println(fieldAnnotation.length());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值