Java学习笔记09(注解和反射)

注解

注解(Annotation)

Annotation 的作用

  • 不是程序本身,可以对程序做出解释;
  • 可以被其他程序(如:编译器 )读取;

几个内置注解

  • @Override // 重写的注解;

  • @Deprecated //不推荐程序员使用,通常是危险的或者存在更好的方法;

  • @SuppressWarnings //镇压警告,可以放在 方法和 类 上;带有参数 “all”,“unchecjed” 等;

元注解

元注解就是负责解释其他注解的注解;Java定义了四个标准的 meta-annotation 类型;

@Tatget : 用于描述注解的使用范围;

@Retention :注解在什么级别是有效的(SOURCE < CLASS < RUNTIME)源码<类<运行时 ;

@Documented : 表示注解是否生成在JAVADOC文档中;

@Inherited : 子类可以继承父类的注解;

@MyAnnotation
public class AnnotationDemo {
    @MyAnnotation
    public void aMethod(){
    };
}

// 自定义一个注解 MyAnnotation
   //元注解
@Target(value = {ElementType.TYPE,ElementType.METHOD})//在类,方法上可以使用注解。  Target表示作用的范围
@Retention(value = RetentionPolicy.RUNTIME)    // 在运行时有效 。      Retention 表示 在什么地方有效
@Documented
@Inherited
@interface MyAnnotation {
}

自定义注解

//自定义注解
@MyAnnotation2(name = "CH")    //若有参数,必须在注解后面加上参数的值, 若注解的参数只有一个,可以将参数名设置为value,设置为value后,可以省									略参数名
public class AnnotationDemo01 {
    @MyAnnotation3({"CH","zqx"})  //只有一个参数 ,且参数名为value, 省略参数名
    public void MyAnnotationtest(){
    }
}

@Target({ElementType.TYPE,ElementType.METHOD})      //元注解
@Retention(RetentionPolicy.RUNTIME)                 //元注解
@interface MyAnnotation2 {
    //定义 注解的参数:  参数类型 + 参数名 + ();
    String name();              //定义一个String  类型的 参数;
    int age() default 0;        //可以加一个默认值,若参数由默认值,可以在 注解的参数列表省略该参数;
}

@Target({ElementType.TYPE,ElementType.METHOD})      //元注解
@Retention(RetentionPolicy.RUNTIME)                 //元注解
@interface MyAnnotation3{
    String[] value();           //只有一个参数,且参数名为 value的注解
}

反射机制

反射:Reflection;

Java是一门动态语言,有了反射机制,让Java成为了准动态语言;反射机制允许程序在执行期借助于 Reflection API 取得任何类的内部信息,并能直接操作任意对象的内部属性及方法;

加载完类之后,在堆内存的方法区中就产生一个Class类型的对象,一个类只有一个Class对象,这个对象就包含了完整的类的结构信息。我们就可以通过这个对象看到类的结构。

获取反射对象

获取反射对象就是获取一个类的 Class 对象;

获取 Class对象方式:

public class ReflectionTest {
    public static void main(String[] args) throws ClassNotFoundException {
        Class c1 = Class.forName("com.ch.Reflection.User");   // 1. 通过 Class类中的 forName()静态方法获取 User 的 Class对象,参数为类的															  全路径,需抛出异常;
        User user = new User();
        Class c2 = user.getClass();          //2.已知一个类的实例,可以通过 实例名.getClass() 方法获得;
        
        Class c3 = User.class;               //3. 知道一个具体的类,通过 类名.class;获得;
       Class c4 = Integer.TYPE;			   // 4 .基本数据包装类 都有一个 TYPR 属性来获取对应的 Class的对象
        //一些方法:
       Class superclass = c1.getSuperclass();  //获取一个类的父类Class对象, 通过 getSuperclass()方法;
                
    }
}
//定义一个实体类 pojo, entity
class User{
    private String name;
    private int id;
    public User(){
        super();
    }
    public User(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setId(int id) {
        this.id = id;
    }
}


一些方法:

	    User user = new User();
        Class c1 = user.getClass();     //得到 User类的 class对象
        //获取类的名字;
        c1.getName();
        c1.getSimpleName();
        //获取类的属性;
        Field[] fields = c1.getFields();//只能得到 public 属性;
        Field[] fields1 = c1.getDeclaredFields();   //可以得到所有属性;
        Field name = c1.getDeclaredField("name"); //获取指定得属性
        //获取类得方法
        Method[] method = c1.getMethods();//只能得到 public 方法,本类和 继承的方法;
        Method[] declaredMethods = c1.getDeclaredMethods(); //获取本类所有的方法,不获取继承的方法
        Method getName = c1.getMethod("getName", null);//获取指定得方法
        Method setName = c1.getMethod("setName", String.class);//获取指定得方法,参数为: 方法名 , 参数的class对象
        //获取构造器
        Constructor[] constructors = c1.getConstructors();//获取类的构造器
        Constructor constructor = c1.getConstructor(String.class, int.class);//获取指定构造器 参数为 类型的class对象

通过class对象创建 类对象;

 Class c1 = Class.forName("com.ch.Reflection.User");//获取User的class对象
        User user = (User) c1.newInstance(); //通过 newInstance()方法创建 对象, 本质是调用了无参构造器,若类中没有无参构造会报错
        //通过构造器创建对象
        Constructor constructor = c1.getConstructor(String.class, int.class);//获取有参构造器;
        User user1 = (User) constructor.newInstance("111", 18);   //通过构造器创建对象;
        //通过反射调用方法;
        Method setName = c1.getDeclaredMethod("setName", String.class);//获取 setName()方法;
        setName.invoke(user1,"晨昏"); // 通过 方法.invoke()方法 设置 值  , 将 user1的 name 设置为 晨昏; invoke 激活(对象,值);
        System.out.println(user1.getName());
        //通过反射操作属性;
        Field name = c1.getDeclaredField("name");//获取私有属性 name
        name.setAccessible(true);//设置 私有属性 必须关闭安全检测   ,通过 setAccessible(true)
        name.set(user1,"晨昏Cc");   //调用set()方法 设置 某对象的 name属性值。  set(对象,值);
        System.out.println(user1.getName());

反射操作注解

///通过反射获取注解
public class ReflectionTest01 {
    public static void main(String[] args) throws NoSuchFieldException {
        Class c1 = Student.class;  //获取 Student 的 Class 对象;
        //通过反射获得注解;
        Annotation[] annotations = c1.getAnnotations();  // 通过 getAnnotations()方法获取所有的注解;
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //获取注解 的 value值;
        TpyeAnnotation typeAnnotation = (TpyeAnnotation)c1.getAnnotation(TpyeAnnotation.class); //获取指定的注解,
        String value = typeAnnotation.value();  //得到注解的 value值
        System.out.println(value);
        //获取属性的注解值
        Field fieldName = c1.getDeclaredField("name");  //获取 name 属性;
        FieldAnnotation annotation = fieldName.getAnnotation(FieldAnnotation.class); //获取 name属性的注解;
        annotation.name();          //获取 注解的属性值
        annotation.type();
        annotation.length();
    }
}

//创建一个实体类
   //给类 属性 加上注解
@TpyeAnnotation("Stuent_tab")
class Student{
    @FieldAnnotation(name = "Student_id",type = "int", length = 10)
    private int id;
    @FieldAnnotation(name = "Student_age",type = "int", length = 10)
    private int age;
    @FieldAnnotation(name = "Student_name",type = "String", length = 10)
    private String name;

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
//创建一个作用在类上的注解
@Target(ElementType.TYPE) //元注解   注解的作用范围为 类;
@Retention(RetentionPolicy.RUNTIME) // 元注解  在运行时有效;
@interface TpyeAnnotation{
    String value();         //注解的一个属性
}
//创建一个作用在属性上的注解
@Target(ElementType.FIELD) //元注解   注解的左右范围为 属性;
@Retention(RetentionPolicy.RUNTIME) // 元注解  在运行时有效;
@interface FieldAnnotation{
    String name();  //字段名
    String type();      //类型
    int length();       //长度
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值