JAVA注解与反射

注解

注解的作用:
不是程序本身,可以对程序做出解释,和注释有相似之处。
可以被其他程序(如编译器)所读取。
注解的格式:以“@注解名”在代码上存在,还可以在其中添加一些参数。
注解在哪里使用:可以附在包,类,方法,字段上面。等于给他们添加了额外的辅助信息。我们可以通过反射机制实现对这些元数据的访问。

注解举例:

@override:重写的注解
@Deprecated:过时的注解

元注解:对注解的注解。有如下四类元注解。

@Target:用于描述注解的使用范围(即被描述的注解可以用在什么地方)
@Retention:表示需要在什么级别保存注释信息,用于描述注解的生命周期(source>class>runtime)
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
自定义注解:使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
声明注解
@interface用来声明一个注解,格式:public @interface 注解名{定义内容} ,其中的每一个方法实际是声明了一个配置参数,方法的名称就是参数的名称,返回值类型就是参数的类型(返回值只能是基本类型,Class,String,enum),可以通过default来声明参数的默认值,如果只有一个参数成员,一般参数为value,注解元素必须要有值,我们定义注解元素时,经常使用空字符串,0作为默认值。

反射

反射概念
JVM为每个加载的class创建了一个Class实例,包含了类的各种信息包括类名,包名,方法,字段,父类,实现的接口,因此我们只要得到了Class实例就可以获取类的相关信息。这种通过Class实例获得class相关信息的方法称为反射。

反射的功能

  1. 在运行时判断任意一个对象所属的类
  2. 在运行时构造任意一个类的对象
  3. 在运行时判断任意一个类所具有的成员变量和方法
  4. 在运行时获取泛型信息
  5. 在运行时调用任意一个对象的成员变量和方法
  6. 在运行时处理注解
  7. 生成动态代理

获取Class实例的方法
注意class在jvm中创建的Class实例是唯一的。

1. Class cls  = string.classs
2. String hello = "hello"
Class cls = hello.getClass()
3. Class cls = Class.forName("java.lang.String")

反射访问字段

//四种方法获取字段
Field getField(name)//根据字段名获取某个pubic的field(包括父类)
Field getDeclaredField(name)//根据字段名获取当前类的field。
Field [] getField()//获取所有public的field(包括父类)
Field [] getDeclareField()//获取当前类的所有field(不包括父类)

实例

package com.south.reflection;

import java.lang.reflect.Field;

public class GetName {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class cls = Class.forName("com.south.reflection.student");
        Field field = cls.getField("name");
        System.out.println(field);
        Field field1 = cls.getField("score");
        //Field field2 = cls.getDeclaredField("grade");
        System.out.println(field1);
        //System.out.println(field2);
    }

}

class person{
    public String name;
}
class student extends person{
    public int score;
    private int grade;

字段值
注意:在调用get前需写一句
f.setAccessible(true)
这是无论该字段是不是public,一律允许访问。

		Object p = new Person("Xiao Ming");
        Class c = p.getClass();
        Field f = c.getDeclaredField("name");
        //获得字段值
        Object value = f.get(p);
        System.out.println(value); // "Xiao Ming"
        //设置字段值
        f.set(p,"xiaohong")

获得方法

  • 通过Class实例的方法可以获取Method实例:getMethod(),getMethods(),getDeclaredMethod(),getDeclaredMethods();
  • 通过Method实例可以获取方法信息:getName(),getReturnType(),getParameterTypes(),getModifiers()其中
    参数为方法名和参数的Class实例。
  • 通过Method实例可以调用某个对象的方法:Object invoke(Object instance, Object… parameters)第一个为调用哪个对象的方法,后面的参数为调用方法的参数。
  • 通过设置setAccessible(true)来访问非public方法;

实例

package com.south.reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class GetName {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        student student = new student();
        Class cls = Class.forName("com.south.reflection.student");
        Method method = cls.getMethod("getName");
        method.setAccessible(true);
        String str = (String) method.invoke(student);
        System.out.println(str);


    }

}

class person{
    public String name;
    public String getName(){
        return name;
    }
}
class student extends person{
    public int score;
    private int grade;
    public int getScore(){
        return score;
    }
    public int grade(){
        return grade;
    }
}

调用构造方法
我们通常通过new创建新的实例,如果用反射机制即获得Class实例后调用newInstance()方法即可创建新的实例。这样创建必须在类中有无参构造函数。如果想通过有参构造函数创建新的实例该如何作?

package com.south.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class GetName {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {

        Class cls = Class.forName("com.south.reflection.student");
        Constructor constructor = cls.getConstructor(int.class);
        student student1 = (student) constructor.newInstance(123);
        System.out.println(student1.score);




    }

}

class person{
    public String name;
    public String getName(){
        return name;
    }
}
class student extends person{
    public int score;
    private int grade;
    public int getScore(){
        return score;
    }
    public int grade(){
        return grade;
    }
    public student(int n){
        this.score=n;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值