JAVA学习--注解

一、注解

1.作用:不是程序本身,可以对程序作出解释;可以被其他程序读取。
2.格式:以"@注释名"在代码中存在,还可以添加一些参数值,如@SuppressWarnings(value=“unchecked”)
3.可以附加在package,class,method,field等上面,可以通过反射机制编程实现对这些元数据的访问。

二、元注解

元注解负责注解其他注解,JAVA定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明。

//Target 表示我们的注解可以用在哪些地方:方法上、类上等
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//Retention 表示我们的注解在什么地方还有效果
//runtime>class>sources 运行时、生成class文件后、源码
@Retention(value = RetentionPolicy.RUNTIME)
//Documented 表示是否将我们的注解生成在JAVAdoc中
@Documented
//Inherited 子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
}

三、注解的定义

注解的参数:参数类型+参数名();
若只有一个参数,名为value则可在括号内直接写参数。

public class Test {
    @MyAnnotation(age = 18,name = "lxy")
    public void test1(){}
}
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation{
    String name();
    int age();
    int id() default -1; //有默认值
    String[] schools() default {"qinghua"};
}

四、反射

加载完类之后,在堆内存的方法中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包括了完整的类的结构信息。Class类是Java反射的源头
反射方式:实例化对象–>getClass()方法–>得到完整的“包类名称”

获取class类的实例
1.若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高。
Class c1 = Person.class;
2.已知某个类的实例,调用该实例的getClass()方法获取Class对象
Class c2 = person.getClass();
3.已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出一个ClassNotFoundException
Class c3 = Class.forName(“demo01.Student”);
4.内置基本数据类型可以直接用类名.Type
5.还可以用ClassLoader

五、类加载

在这里插入图片描述
1.字节码.class文件加载到内存,所有类都会产生一个对应的class对象。
2.链接,将所有的静态变量初始化为0。
3.初始化:类初始化(new)时()方法执行静态代码,静态变量赋值。
在这里插入图片描述

六、获取类的运行时结构

package com.ayu.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class aClass = Class.forName("com.ayu.reflection.User");
        System.out.println(aClass.getName()); //com.ayu.reflection.User
        System.out.println(aClass.getSimpleName());//User
      //获取类变量:只能获得public的
        Field[] fields = aClass.getFields();
        for (Field field:fields){
            System.out.println(field);
        }
        //获取类变量:能获得所有的
        fields = aClass.getDeclaredFields();
        for (Field field:fields){
            System.out.println(field);
        }
		//获取特定变量
        System.out.println(aClass.getDeclaredField("name"));
       //获取类方法:public
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        //获取类方法:all
        methods = aClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
		//获取特定方法
        Method getName = aClass.getMethod("getName",null);
        Method setName = aClass.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);
    }
        //获取构造器
       Constructor[] constructors = aClass.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        constructors = aClass.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println(declaredConstructor);

}

六、动态创建对象执行方法

创建类的对象:调用Class对象的newInstance()方法

  • 类必须有一个无参构造器
  • 类的构造器的访问权限要足够
    没有无参构造器时,只需要在操作的时候明确调用类中的构造器,并将参数传递进去后,才可以实例化操作。
    1)通过Class类的 getDeclaredConstructor(class…parameterTypes)取得本类的指定形参类型的构造器。
    2)向构造器的形参中传递一个对象数组进去,里面包含了构造器所需的各个参数。
    3)通过Constructor实例化对象
        Class c1 = Class.forName("oop.demo02.Student");
        //	本质是调用类的无参构造,如果没有无参构造,则需要先获取构造器
        Student student = (Student) c1.newInstance();
        System.out.println(student);


		//获取构造器
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class);
        //使用构造器创建对象
        Student s2 = (Student) declaredConstructor.newInstance("ayu",18);
        System.out.println(s2);        
        Student s3 = (Student) c1.newInstance();
        
        //获取方法,通过反射调用方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        //invoke 为s3调用setName方法,并传值
        setName.invoke(s3,"lxy"); 
        System.out.println(s3.getName());
        
		//通过反射操作属性
        Field declaredField = c1.getDeclaredField("age");
        declaredField.setAccessible(true); //设置为true即可操作私有属性
        declaredField.set(s3,19);
        System.out.println(s3);

setAccessible:Method和Field、Constructor对象都有setAccessible()方法,其作用为启动和禁用访问安全检查的开关。true为取消检查,使得原本无法访问的私有成员也可以访问。

七、获取注解信息

package com.kuang.reflection;

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

public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("com.kuang.reflection.Student2");
        Annotation[] annotation = c1.getAnnotations();
        for (Annotation annotation1 : annotation) {
            System.out.println(annotation1);
        }//@com.kuang.reflection.Tableayu(value=db_table)
        //获得注解的value值,要强制转换才能获取到.value()
        Tableayu annotation1 = (Tableayu)c1.getAnnotation(Tableayu.class);
        System.out.println(annotation1.value());//db_table
		//获得指定属性的注解值
        Field name = c1.getDeclaredField("name");
        Fieldayu annotation2 = name.getAnnotation(Fieldayu.class);
        System.out.println(annotation2.column());//db_name

    }
}
@Tableayu("db_table")
class Student2{
    @Fieldayu(column = "db_name",type = "varchar",length = 10)
    String name;
    @Fieldayu(column = "db_id",type = "int",length = 10)
    int id;
    @Fieldayu(column = "db_age",type = "int",length = 10)
    int age;

    public Student2() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Tableayu{
    String value();
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldayu{
    String column();
    String type();
    int length();
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值