注解和反射

注解和反射

注解【Annotation】

已有的注解

@Override/@SuppressWarnings

元注解

  • 常见有两个,用来自定义注解

@Target表示注解要用在什么地方

@Retention表示注解在什么时候有效,源码/编译,一般自定义的注解都用Runtime

自定义注解

//类上的注解
@Annotation2("成功") //因为此注解只有一个参数,可以不写value=
public class Annotation {
    //方法上的注解
    @MyAnnotation(n = -1, x = 'a')  //不能直接写-1,'a'必须加上 n=,x=
    public void function() {

    }
}
//自定义注解1
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    //参数类型,参数名,可以有默认值
    String name() default "yes"; //如果有default,注解就可以不给参数,否则一定要参数
    int n();
    char x();
}
//自定义注解2
@Target({ElementType.METHOD,ElementType.TYPE})  //TYPE表示作用域在类上
@Retention(RetentionPolicy.RUNTIME)
@interface Annotation2 {
    String value(); //如果注解只有一个参数,可以定义成value(),注解实现的时候就不用写value=...
}

反射【Reflection重点】

  1. 反射是干嘛的?

在运行的过程中可以获取类的任意属性,太太太猛了!直接让JAVA可以称为一门动态语言

怎么获得Class对象

  • 几乎所有的类型都有Class对象
public class MyClass {
    public static void main(String[] args) throws Exception {
        Person person = new Student("学生");
        //获取Class对象方法1
        Class c1=person.getClass();
        System.out.println(c1.hashCode());
        //方法2
        Class c2 = Class.forName("com.xu.day12.Student");
        System.out.println(c2.hashCode());
        //方法3
        Class c3 = Student.class;
        System.out.println(c3.hashCode());
        //通过Class对象可以获取类的很多属性
        System.out.println(c1.getSuperclass());
        System.out.println(c1.getName());
        System.out.println(c1.toString());
    }
}

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(String name) {
        super(name);
    }
}

class Teacher extends Person {
    public Teacher(String name) {
        super(name);
    }
}
//输出
356573597
356573597
356573597
class com.xu.day12.Person
com.xu.day12.Student
class com.xu.day12.Student

通过反射动态创建一个类的对象,调用其构造方法、普通方法、修改其属性

  • 通过反射获得对象类型是Object,方法类型是Method,属性类型是Field
public class MyClass {
    public static void main(String[] args) throws Exception {
        Class c1 = Class.forName("com.xu.day12.Person");
        //用反射动态创建对象方法一
        Person p1 = (Person) c1.newInstance();  //此方法是通过调用类的无参构造来实现的
        //一旦类没有无参构造的时候,方法一就不可行了
        //创建对象方法二
        Constructor cons=c1.getConstructor(char.class, String.class, int.class);  //注意此处的写法
        Person p2=(Person) cons.newInstance('男',"小明",100);
        System.out.println(p2.toString());
        //通过反射获取类的方法
        java.lang.reflect.Method method=c1.getDeclaredMethod("setName", String.class);//注意此处的参数,需要先输入name再输入类型
        method.invoke(p1,"小王"); //此处调用方法需要先传入对象才行
        System.out.println(p1.getName());
        //通过反射修改类的属性
        Person p3=(Person)c1.newInstance();
        Field field=c1.getField("age");
        field.setAccessible(true); //这是安全检查的开关,注意,如果不加这句话,私有属性不可修改
        field.set(p3, 888);
        System.out.println(p3.getAge());
    }
}

class Person {
    public char sex;
    private String name;
    private int age;
    public Person() {
        System.out.println("无参构造被调用了");
    }

    public Person(char sex, String name, int age) {
        this.sex = sex;
        this.name = name;
        this.age = age;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    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 "Person{" +
                "sex=" + sex +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

通过反射操作泛型

了解即可

通过反射操作注解【重点】

public class GetAnnotationByReflection {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        //获取类的注解
        Class c = Class.forName("com.xu.day12.Student");
        TableName annotation = (TableName) c.getAnnotation(TableName.class);//重点:这句话的意思是获取TableName类型的注解
        System.out.println(annotation.value());
        //获取属性的注解
        Field field=c.getField("id"); //需要先获取属性
        TableField annotation2=field.getAnnotation(TableField.class); //传入参数是此属性的注解类型TableField
        System.out.println(annotation2.clumnName());
        System.out.println(annotation2.type());
        System.out.println(annotation2.lenth());
    }

}
@TableName("db_Student")
class Student {
    @TableField(clumnName = "db_id",type = "int",lenth = 10)
    private int id;
    @TableField(clumnName = "db_age",type = "int",lenth = 10)
    private int age;
    @TableField(clumnName = "db_name",type = "String",lenth = 10)
    private String name;

    public Student() {
    }

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

@Target(ElementType.TYPE) //作用域是类
@Retention(RetentionPolicy.RUNTIME)
@interface TableName {
    String value();
}
@Target(ElementType.FIELD) //作用域是类
@Retention(RetentionPolicy.RUNTIME)
@interface TableField {
    String clumnName();
    String type();
    int lenth();
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值