注解与反射

一、注解

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


/**
 * 元注解
 */
@MyAnnotation
public class Demo01 {
    @MyAnnotation
    public void test(){

    }
}
//自定义一个注解
//@Target表示注解可以用在哪些地方 下面的例子表面可以用在类以及方法上
@Target(value = {ElementType.TYPE,ElementType.METHOD})
//@Retention 表示在什么地方注解还有效 source<class<runtime 若是source 则表明注解在源码中有效
// 编译后形成class文件后注解无效,通常采用runtime
@Retention(value = RetentionPolicy.RUNTIME)
//@Documented 表示是否将注解生成在javadoc中
@Documented
//@Inherited 表示子类可以继承父类的注解
@Inherited
@interface MyAnnotation{//注意一个类里面只要能有一个public 所以此注解不可以加上public 会报错
}

在这里插入图片描述


/**
 * 自定义注解
 */
@MyAnnotation3("zzz")
public class Demo02 {
    @MyAnnotation2(num=10,name="zfc")//注解的参数没有顺序
    public void test(){
    }
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
    String name();//注意这不是方法 这是注解的参数 如果注解有参数 那么在使用时 必须写明参数 否则报错
    int age() default 0;//当然也可以写明参数 这样的话使用时可以不写
    int num();
    String[] schools() default {"西交大","西电"};
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
    String value();//如果注解只有一个参数 那么使用value,并且在使用时可以省略value,只写参数 其他的则不行
}

二、反射

在这里插入图片描述

  • 获得反射对象
    反射就是通过对象反射求出类名的过程
public class Demo01 {
    public static void main(String[] args)throws ClassNotFoundException {
        //通过反射获取类的class对象
        Class c1 = Class.forName("reflection.User");
        System.out.println(c1);
        Class c2 = Class.forName("reflection.User");
        Class c3 = Class.forName("reflection.User");
        Class c4 = Class.forName("reflection.User");
        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());//所有的hashcode都一样 因此一个类只有一个class对象并且一个类被加载后,其类结构就会被封装在class对象中

    }
}

在这里插入图片描述

 public static void main(String[] args) throws ClassNotFoundException{
        Student student = new Student();
        //方式一:通过对象获得class类对象
        Class c1 = student.getClass();
        System.out.println("c1:"+c1.hashCode());

        //方式二:通过forname获得class类对象
        Class c2 = Class.forName("reflection.Student");
        System.out.println("c2:"+c2.hashCode());

        //方式三:通过类名.class获得class类对象
        Class c3 = Student.class;
        System.out.println("c3:"+c3.hashCode());

        //获得父类
        Class superclass = c1.getSuperclass();
        System.out.println(superclass);
    }

在这里插入图片描述

  • 获取类的信息
 public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        /**
         * 总结:1.不带Declared是获取共有,带Declared是公有私有都会获取
         *       2.带参数的是获得指定的,不带参数的是获得所有
         */
        Class c1 = Class.forName("reflection.User");

        //获取包名+类名
        String name = c1.getName();
        System.out.println("包名+类名:"+name);

        //获取类名
        String simpleName = c1.getSimpleName();
        System.out.println("类名:"+simpleName);

        //获取所有属性
        Field[] fields =c1.getFields();//获得所有公有属性
        for (Field field : fields) {
            System.out.println("公有属性:"+field);
        }
        Field[] declaredFields = c1.getDeclaredFields();//获得所有属性公有+私有
        for (Field declaredField : declaredFields) {
            System.out.println("公有+私有属性:"+declaredField);
        }

        //获得指定属性
        Field sch = c1.getField("sch");//这个是获得指定的公有属性
        System.out.println("获得指定属性:"+sch);

        Field id = c1.getDeclaredField("id");//这个是获得指定的属性 私有和公有
        System.out.println("获得指定属性:"+id);

        //获得方法
        Method[] methods = c1.getMethods();//获得本类和父类的所有公有方法
        for (Method method : methods) {
            System.out.println("获得方法:"+method);
        }
        System.out.println("-------------------------------------------");
        Method[] declaredMethods = c1.getDeclaredMethods();//获得本类的所有私有和公有方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println("获得方法:"+declaredMethod);
        }

        //获得指定方法
        Method getAge = c1.getMethod("getAge");//获得指定的共有方法
        System.out.println("获得指定方法:"+getAge);

        Method setAge = c1.getDeclaredMethod("setAge", int.class);//获得指定的私有公有方法
        System.out.println("获得指定方法:"+setAge);

        //获得构造器
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("获得所有构造器:"+constructor);
        }

        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor constructor : declaredConstructors) {
            System.out.println("获得所有构造器:"+constructor);
        }
        //获得指定构造器
        Constructor constructor = c1.getConstructor(String.class, int.class, int.class, String.class);
        System.out.println("获得指定构造器:"+constructor);
    }

通过反射获取对象、操作对象
 public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException,NoSuchMethodException, InvocationTargetException,NoSuchFieldException{
        //根据class对象创建一个类的对象
        Class c1 = Class.forName("reflection.User");
        User user = (User) c1.newInstance();//默认创建出来是object类型 但已知是创建的user 因此转换成user
        System.out.println(user);//打印出来的属性都是空值 本质上是调用了无参构造函数 如果将类里面的无参构造函数 删除 则程序会报错
        //User{name='null', id=0, age=0}
        
        //根据构造器创建对象 可以对对象的属性赋值
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
        User user1 = (User)declaredConstructor.newInstance("ZZZ", 001, 20);
        System.out.println(user1);//User{name='ZZZ', id=1, age=20}

        //操作对象的方法
        //获取方法
        Method declaredMethod = c1.getDeclaredMethod("setAge", int.class);
        //激活方法
        declaredMethod.invoke(user1,100);
        System.out.println(user1);//User{name='ZZZ', id=1, age=100}

        //操作对象的属性
        //获取属性
        Field name = c1.getDeclaredField("name");
        //如果删除这句话 则会报错 因为无法操作私有属性 因此必须加上这句话 关闭安全检测
        name.setAccessible(true);
        //操作属性
        name.set(user1,"ddd");
        System.out.println(user1);//User{name='ddd', id=1, age=100}


    }

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过反射获取注解
public static void main(String[] args) throws ClassNotFoundException,NoSuchFieldException{
        Class c1 = Class.forName("reflection.Demo05");
        //获取类的注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        //获取指定注解的值
//        Annotation5 annotation = (Annotation5) c1.getAnnotation(Annotation5.class);
//        String value = annotation.value();
//        System.out.println(value);
       //获得指定属性的注解
//        Field name = c1.getDeclaredField("age");
//        Annotation6 annotation1 = name.getAnnotation(Annotation6.class);
//        System.out.println(annotation1.column());
//        System.out.println(annotation1.length());
//        System.out.println(annotation1.type());


    }
}

@Annotation5("db_Teacher")
class Teacher {
    @Annotation6(column = "db_name",type = "varchar",length = 3)
    private String name;
    @Annotation6(column = "db_age",type = "int",length = 3)
    private int age;

    public Teacher() {
    }

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

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

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

}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Annotation5 {
    String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Annotation6 {
    String column();
    String type();
    int length();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值