Java反射和注解符的使用

本文介绍了Java反射的使用,包括访问构造方法、成员变量和成员方法。同时,讲解了如何利用注解创建自定义元注解@Retention和@Target。
摘要由CSDN通过智能技术生成

Java反射使用示例

1、访问构造方法

访问方法返回值类型说明
Class.getConstructors()Constructor型数组获得所有访问权限为public的构造方法
Class.getDeclaredConstructors()Constructor型数组获得所有构造方法
Class.getConstructor(Class<?>…parameterTypes)Constructor对象获得权限为public的指定构造方法
Class.getDeclaredConstructor()Constructor对象获得指定的构造方法
Constructor.getModifiers()获得权限修饰符
Constructor.getName()构造方法的名字
Constructor.getParameterTypes()Class[]构造方法的参数类型(String,int,double)
//public T newInstance(Dbjece ...initargs);  //Constructor构造对象
/**
Example.java
*/
public class Example {
    private int id;
    private String name;
    private double price;

    public Example() {
    }

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

    private Example(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
    public void doIt(){
        System.out.println("doIt函数被调用了!");
    }
	private void add(int x,int y){
        System.out.println(x+" + "+y+" = "+(x+y));
    }
    
    @Override
    public String toString() {
        return "Example{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

/**
Main.java
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
public class Main {
    public static void main(String[] args) {
        try {
            Class<Example> c = Example.class;  //获取一个class对象
            Constructor[] constructor = c.getDeclaredConstructors();//获得所有权限的构造函数 getConstructors() 只能获取public的构造函数
            for (Constructor con:constructor) { //遍历输出这些构造函数
                System.out.print(Modifier.toString(con.getModifiers())+" "); //输出当前构造函数的权限修饰符
                System.out.print(con.getName()+"("); //输出函数名字
                Class[] paras =  con.getParameterTypes(); //获取参数列表
                for (int i=0;i<paras.length;i++){ //遍历输出参数列表
                    System.out.print(paras[i].getSimpleName()+" args "); //获取当前参数修饰符(String,int,double...)
                    if (i<paras.length-1){
                        System.out.print(",");
                    }
                }
                System.out.println(")");
            }
            Constructor<Example> cs = c.getDeclaredConstructor(int.class,String.class,double.class); //获取指定的构造函数
            cs.setAccessible(true);  //获取权限如果不获取权限就只能用public修饰的构造函数
            Example obj = cs.newInstance(-1,"胡晓龙",1); //创建一个对象
            System.out.println(obj.toString());
            obj.doIt();
        } catch (NoSuchMethodException e) {
            System.out.println("没有找到对应的方法"); //getDeclaredConstructor()可能会引发这个异常
            e.printStackTrace();
        } catch (InstantiationException e) {
            System.out.println("不能实例化对象异常"); //cs.newInstance()可能引发这个异常
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            System.out.println("反射异常"); //cs.newInstance() 可能引发这个异常
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            System.out.println("没有访问权限"); //如果没有cs1.setAccessible(true) 就会已发这个异常
            e.printStackTrace();
        }
    }
}


/**
输出结果

private Example(int args ,String args ,double args )
public Example(int args ,String args )
public Example()
Example{id=-1, name='胡晓龙', price=1.0}
doIt函数被调用了!
*/


2、访问成员变量

访问方法返回值类型说明
Class.getFields()Field数组获得所有权限为public的成员变量
Class.getField()Field对象获得指定的权限为public的成员变量
Class.getDeclaredFields()Field数组获得所有成员变量
Class.getDeclaredField()Field对象获得指定成员变量
Field.getModifiers()获得成员变量权限修饰符(public,private)
Field.getName()获得成员变量的名字
Field.getType()获得成员变量的声明类型(String,int,double…)
Field.get(Class)获取相应Class对象的某一个成员变量值
Field.set(Class,args)修改相应Class对象的某一个成员变量值
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;

public class Main {
    public static void main(String[] args) {
        Class<Example> exampleClass = Example.class;
        Field[] fields = exampleClass.getDeclaredFields();
        for (Field field: fields) {
            System.out.print(Modifier.toString(field.getModifiers())+" ");
            System.out.print(field.getName()+" ");
            System.out.print(field.getType().getSimpleName());
            System.out.println();
        }
        try {
            Constructor<Example> ex = exampleClass.getDeclaredConstructor(int.class,String.class,double.class);
            ex.setAccessible(true);
            Field field = exampleClass.getDeclaredField("name");
            field.setAccessible(true);
            Example example = ex.newInstance(1,"胡晓龙",10);
            System.out.println(field.get(example)); //获取example对象的成员变量值
            field.set(example,"张前"); //修改example对象的成员变量值
            System.out.println(field.get(example));
        } catch (NoSuchMethodException e) { //没有找到对应的方法
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            //如果没有field.setAccessible(true) ex.setAccessible(true) 就会已发这个异常
            System.out.println("没有访问权限"); 
            e.printStackTrace();
        } catch (InstantiationException e) {
            System.out.println("不能实例化对象异常"); //ex.newInstance()可能引发这个异常
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            System.out.println("反射异常"); //ex.newInstance() 可能引发这个异常
            e.printStackTrace();
        } catch (NoSuchFieldException e) { //没有找到对应的成员变量
            System.out.println("未找到相应成员变量");
            e.printStackTrace();
        }
    }
}

/**
private id int
private name String
private price double
胡晓龙
张前
*/

3、访问成员方法

访问方法返回值类型说明
Class.getMethods()Method型数组获得访问权限为public的方法
Class.getMethod(String name,Class<?>…parameterTypes)Method对象获得权限为public的方法name为方法名后面是参数列表
Class.getDeclaredMethods()Method型数组获得所有方法
Class.getDEclaredMethod(String name,Class<?>…parameterTypes)Method对象获得指定方法
invoke(Object obj,Object…args)调用成员方法
method.getModifiers()获取修饰符
method.getName()获取方法名
method.getParameterTypeClass[]获得参数类型列表(String,int,double…)
import java.lang.reflect.*;
public class Main {
    public static void main(String[] args) {
        Class<Example> exampleClass = Example.class;
        Method[] modifiers = exampleClass.getDeclaredMethods();
        for (Method method:modifiers) {
            System.out.print(Modifier.toString(method.getModifiers())+" ");
            System.out.print(method.getName()+"(");
            Class[] classes = method.getParameterTypes();
            for (int i=0 ;i<classes.length;i++){
                System.out.print(classes[i]+" args");
                if (i<classes.length-1){
                    System.out.print(",");
                }
            }
            System.out.println(")");
        }
        try {
            Constructor<Example> exampleConstructor = exampleClass.getDeclaredConstructor(int.class,String.class,double.class); //获取指定的构造函数
            exampleConstructor.setAccessible(true);
            Example example =  exampleConstructor.newInstance(1,"胡晓龙",2);
            Method method = exampleClass.getDeclaredMethod("add",int.class,int.class);
            method.setAccessible(true);
            method.invoke(example,1,2); //调用方法
        } catch (NoSuchMethodException e) {
            //未找到方法异常
            e.printStackTrace();
        } catch (InstantiationException e) {
            System.out.println("不能实例化对象异常"); //cs.newInstance()可能引发这个异常
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            System.out.println("反射异常"); //cs.newInstance() 可能引发这个异常
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            System.out.println("没有访问权限"); //如果没有cs1.setAccessible(true) 就会已发这个异常
            e.printStackTrace();
        }
    }
}
/**
private add(int args,int args)
public toString()
public doIt()
1 + 2 = 3
*/

3、使用Annotation创建自定义注解符号

public @interface MyAnnotation{
    String value() default "默认值";  //String:成员类型。可用的成员变量类型有String、Class、primitive、enumerated和annotation...
    Class type() default void.class;  //default "默认值"
}

元注解

注解符功能
@Decumented指示某一类型的注解通过javadoc和类似的默认工具进行文档初始化
@Inherited指示注释类型被自动继承
@Rectention指示注解类型的注释要保留多久
@Target指示注释类型所适应的程序元素的种类

@Retention

枚举常量说明
SOURCE不编译Annotation到类文件中
CLASS编译Annotation到类文件中,运行时不加载
RUNTIME在运行时加载到JVM中(运行时能看到,反射注解的前提)

@Target

枚举常量说明
ANNOTATION_TYPE用于Annotation类型
TYPE用于类、接口和枚举,以及Annotation类型
CONSTRUCTOR用于构造方法
FIELD用于成员变量和枚举常量
METHOD用于方法
PARAMETER用于参数
LOCAL_VARIABLE用于局部变量
PACKAGE用于包
方法说明
isAnnotationPresent(Class annotationClass)查看是否添加了指定的注解
getAnnotation(Class annotationClass)获取指定的注解
getAnnotation()获取所有注解的数组
/**
MyAnnotation.java
*/
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "默认值";
    Class type() default void.class;
}

/**
Main.java
*/
import java.lang.reflect.Field;
public class Main {
    public static void main(String[] args) {
        Class<Student> studentClass = Student.class;
        Field[] fields = studentClass.getDeclaredFields();
        for (Field field:fields) {
            if (field.isAnnotationPresent(MyAnnotation.class)){
                MyAnnotation myAnnotation =field.getAnnotation(MyAnnotation.class);
                System.out.print( field.getName()+"已经被注解了! ");
                System.out.println("注解内容为:"+myAnnotation.value());
            }
        }
    }
}
/**
id已经被注解了! 注解内容为:学生的ID
name已经被注解了! 注解内容为:学生的名字
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值