注解与反射笔记

注解

元注解:
@Target:表明被注解注解的作用域(类、方法、属性等等)
@Retention:表明被注解注解的作用时间。只有三个(只在源文件、编译时保留、运行时保留)。一般自定义的注解都设置为运行时保留
@Document:表明被注解的注解会保留在doc文档中
@Inherited:表明被注解的注解所在类的子类可以继承该注解

注解的变量:
注解的变量声明方法是:返回值类型 变量名();(可以设置默认值)

自定义注解:
自定义注解的声明:
@interface 注解名{
}

注解事项:
如果注解有参数,那么除非参数名为value,否则在填写参数的时候必须带上参数名。如age =…;

class DeprecatedTest{
    @Deprecated//表明方法已经过时但是仍可以使用
    public void a(){
        System.out.println("不建议使用");
    }
}

class OverrideTest{
    @Override//表明要重写父类方法,如果写的方法父类没有的话会报错
    public String toString(){
        super.toString();
        return "重写注解";
    }
}

class SuppressWarningsTest{
@SuppressWarnings("all")//抑制警告
    public void test(){
        List list =new ArrayList();
    }
}

@myannotation(name ="da",age =10,schools = "adad")//自定义的注解
class AnnotationTest2{
    @myannotation2("ada")
    public void Test(){

    }
}

//自定义注解
@Target({ElementType.METHOD,ElementType.TYPE})//元注解。定义myannotation注解的作用域
@Retention(RetentionPolicy.RUNTIME)//元注解。定义myannotation注解的作用时间
@Documented//元注解。表明myannotation注解会被包含在doc文档中
@Inherited//元注解。表明子类可以继承myannotation注解
@interface myannotation{
    String name() default "";
    int age()default -1;//如果默认值为-1表示不存在,找不到值。类似于indexof方法,找不到也是返回-1
    String [] schools() default {"adad","adad"};
}

//自定义的注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface myannotation2{
    String value();//只有名字是value才能在使用的时候默认不写名字。换成其他名字不可以
}

反射

获取 Class实例的五个方法:

1.使用类名获得

Class c1 =类名.class();

2.使用对象获得

class a =new class();
Class c2 =a.getClass();

3.通过forName方法获得

Class c3 =Class.forName("");//参数填所要获得类的相对路径,从包开始

4.包装类的Class实例可以通过Type属性获得

Class c4 =Integer.TYPE;

5.通过子类的Class实例获得父类的Class实例

Class c5 =c1.getSuperclass();

以下是练习代码:

class ReflectionTest{
    public static void main(String[] args) throws Exception{
        //一个类只能有一个Class类对象

        //通过forName方法获取对应类的Class实例
        Class c1 = Class.forName("user");
        System.out.println(c1);
        System.out.println(c1.hashCode());

        //通过类名获得。获取Class实例的最安全可靠高效的方法。
        Class c2 =user.class;
        System.out.println(c2);
        System.out.println(c1.hashCode());

        //获取Class实例的另一种方法.通过类的对象获得
        user u1 =new user();
        Class c3 =u1.getClass();
        System.out.println(c3);
        System.out.println(c1.hashCode());

        //基本内置类型的包装类有一个Type属性。可以获得包装类的Class实例
        Class i1 = Integer.TYPE;
        System.out.println(i1);
        System.out.println(i1.hashCode());

        //获得父类的Class实例.在这里user类继承了demo14类(注意用的是c1,是user类的CLass实例)
        Class s1 =c1.getSuperclass();
        System.out.println(s1);
        System.out.println(s1.hashCode());

        
        //所有类型的Class
        Class a1 =Object.class;//类
        Class a2 =Comparable.class;//接口
        Class a3 =String[].class;//一维数组
        Class a4 =float[][].class;//二维数组
        Class a5 =Override.class;//注解
        Class a6 =ElementType.class;//枚举
        Class a7 =Integer.class;//基本数据类型
        Class a8 =void.class;//void
        Class a9 =Class.class;//Class
        System.out.println(a1);
        System.out.println(a2);
        System.out.println(a3);
        System.out.println(a4);
        System.out.println(a5);
        System.out.println(a6);
        System.out.println(a7);
        System.out.println(a8);
        System.out.println(a9);
    }
}

class user extends demo14{
    private int id;
    private String name;
    private int age;

    public user() {
    }

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

    public int getId() {
        return id;
    }

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

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

反射获取包名和类名的方法

getName();//获取包名+类名
getSimpleName();//获取类名
 Class userClass = user.class;
        System.out.println("-----------获得包名+类名----------");
        System.out.println(userClass.getName());//获得包名+类名
        
        System.out.println("-----------获得类名----------");
        System.out.println(userClass.getSimpleName());//获得类名

输出结果:

-----------获得包名+类名----------
user
-----------获得类名----------
user

反射获得构造器

getConstructors();//获得所有public的构造器
getDeclaredConstructors();//获得所有构造器
getDeclaredConstructor(int.class,String.class,int.class));//获得指定的构造器,参数为构造器参数的类型
System.out.println("-----------获得public构造器----------");
        Constructor[] constructors = userClass.getConstructors();
        for (Constructor c:constructors) {
            System.out.println(c);
        }

        System.out.println("-----------获得所有构造器----------");
        Constructor[] constructor1 = userClass.getDeclaredConstructors();
        for (Constructor c1:constructor1) {
            System.out.println(c1);
        }

        System.out.println("-----------指定的构造器----------");
        System.out.println(userClass.getDeclaredConstructor(int.class,String.class,int.class));

输出结果:

-----------获得public构造器----------
public user()
public user(int,java.lang.String,int)
-----------获得所有构造器----------
public user()
public user(int,java.lang.String,int)
-----------指定的构造器----------
public user(int,java.lang.String,int)

反射获得类的属性以及方法
1.属性:

getFields();//获得所有public的属性
getDeclaredFields();//获得所有的属性,包括private
getDeclaredField("name"));//指定要获得的属性,参数为属性名,String类型
System.out.println("-----------获得所有public属性----------");
        Field[] fields = userClass.getFields();//
        for (Field a:fields) {
            System.out.println(a);
        }

        System.out.println("-----------获得所有属性----------");
        Field[] fields1 = userClass.getDeclaredFields();
        for (Field a:fields1) {
            System.out.println(a);
        }

        System.out.println("-----------获得指定的属性----------");
        System.out.println(userClass.getDeclaredField("name"));

输出结果:

-----------获得所有public属性----------
-----------获得所有属性----------
private int user.id
private java.lang.String user.name
private int user.age
-----------获得指定的属性----------
private java.lang.String user.name

2.方法:

getMethods();//获得所有public的方法
getDeclaredMethods();//获得所有的方法,包括private修饰的
getMethod("setName",String.class));//获得指定的方法。第一个参数为方法名,第二个为参数类型	
System.out.println("-----------获得本类及其父类的public方法 ----------");
        Method[] methods = userClass.getMethods();
        for (Method m :
                methods) {
            System.out.println(m);
        }

        System.out.println("-----------获得本类所有的方法----------");
        Method[] methods1 = userClass.getDeclaredMethods();
        for (Method m :
                methods1) {
            System.out.println(m);
        }

        System.out.println("-----------获得指定的方法----------");
        System.out.println(userClass.getMethod("getName", null));
        System.out.println(userClass.getMethod("setName",String.class));

输出结果:

-----------获得本类及其父类的public方法 ----------
public java.lang.String user.getName()
public java.lang.String user.toString()
public void user.setName(java.lang.String)
public void user.setAge(int)
public int user.getAge()
public void user.setId(int)
public static void demo14.main(java.lang.String[])
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
-----------获得本类所有的方法----------
public java.lang.String user.getName()
public java.lang.String user.toString()
public void user.setName(java.lang.String)
private int user.getId()
public void user.setAge(int)
public int user.getAge()
public void user.setId(int)
-----------获得指定的方法----------
public java.lang.String user.getName()
public void user.setName(java.lang.String)

通过反射创建对象
使用newInstance()方法
话不多说,直接上码

		System.out.println("-----------用Class创建对象----------");
        user u = (user) userClass.newInstance();//调用user类的无参构造器。如果没有无参构造器则返回异常
        System.out.println(u);

        System.out.println("-----------用构造器创建对象----------");
        Constructor constructor = userClass.getConstructor(int.class, String.class, int.class);//得到一个构造器
        user u1  = (user) constructor.newInstance(0, "棋棋", 21);
        System.out.println(u1);

通过反射获得属性
使用set()方法可以设置属性的值。代码中的两个参数分别为要将方法传给哪个对象以及方法的参数。
使用get()方法可以获得属性的值。
需要注意的是: 属性为私有变量的话在操作的时候需要使用setAccessible()方法关闭检测。

        System.out.println("-----------通过反射操作属性----------");
        //不能直接操作私有属性。通过关闭程序的安全检测.属性或者方法的setAccessible(true)
        user u4 = (user) userClass.newInstance();
        Field id = userClass.getDeclaredField("id");
        id.setAccessible(true);//取消安全监测
        id.set(u4, 1);
        System.out.println(id.get(u4));
        System.out.println(id.getName());

输出结果:

-----------通过反射获得属性----------
1
id

通过反射操作方法
使用invoke()方法可以对反射获得的方法进行操作。参数为要将方法传入的对象以及给方法传入的值。需要注意的是如果方法为静态方法,则第一个参数可以为null,如果方法没有参数第二个参数可以为null。

System.out.println("-----------通过反射获得方法并激活----------");
        user u2 = (user)userClass.newInstance();//通过Class创建对象。
        Method setName = userClass.getDeclaredMethod("setName", String.class);//通过Class获得一个方法。
        //invoke:激活的意思、invoke()方法的参数为(对象,“给方法输入的值”)
        setName.invoke(u2,"棋棋");//把获得的方法设置参数,并把这个方法交给指定的对象
        System.out.println(u2.getName());

        Method setAge= userClass.getDeclaredMethod("setAge", int.class);//通过Class获得一个方法。
        //invoke:激活的意思、invoke()方法的参数为(对象,“给方法输入的值”)
        setAge.invoke(u2,10);//把获得的方法设置参数,并把这个方法交给指定的对象
        System.out.println(u2.getAge());

        user u3= (user)userClass.newInstance();
        Method getName = userClass.getDeclaredMethod("getName");
        getName.invoke(u3);
        System.out.println(u3.getName());

        //调用私有方法
        Method getId = userClass.getDeclaredMethod("getId");
        getId.setAccessible(true);
        System.out.println(getId.invoke(u3));

输出结果:

-----------通过反射获得方法并激活----------
棋棋
10
null
0

通过反射获得注解

先把需要的类以及注解定义好

@table("db")
class student02{
    @field(columnName = "db_id",type = "int",length = 10)
    private int id;
    @field(columnName = "db_age",type = "int",length = 10)
    private int age;
    @field(columnName = "db_name",type = "varchar",length = 10)
    private String name;

    public student02() {
    }

    public student02(int id, int age, String name) {
        this.id = id;
        this.age = age;
        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;
    }

    public String getName() {
        return name;
    }

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

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

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

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

通过反射获得注解
使用getAnnotations()方法可以获得注解。

        System.out.println("----------通过反射获得注解-----------");
        //通过反射获得注解
        Class c1 = student02.class;
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation a:annotations) {
            System.out.println(a);
        }

输出结果:

----------通过反射获得注解-----------
@table("db")

若需要获得类注解的值,需要调用value()方法。

System.out.println("----------获得注解的value值-----------");
        //获得注解的value值
        table t =(table)c1.getAnnotation(table.class);
        System.out.println(t.value());

输出结果:

----------获得注解的value值-----------
db

而若想要获得属性或者方法的注解的值,可以直接通过接收回来的注解用来获得。

        System.out.println("----------获得类指定的注解的值-----------");
        //获得类指定的注解
        Field f = c1.getDeclaredField("id");
        field annotation = f.getAnnotation(field.class);
        System.out.println(annotation.columnName());
        System.out.println(annotation.type());
        System.out.println(annotation.length());

输出结果:

----------获得类指定的注解的值-----------
db_id
int
10
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值