java 反射基础

java 反射基础

1. 什么是反射?

主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。本质就是在运行时识别对象和类的信息。

2. 为什么需要反射?

通过反射,我们能够

  • 在运行时检测对象的类型;
  • 动态构造某个类的对象;
  • 检测类的属性和方法;
  • 任意调用对象的方法;
  • 修改构造函数、方法、属性的可见性

3. Class对象

3.1 获取方式

想在运行时使用类型信息,必须获取对象Class对象的引用,获取Class有三种方式

1. Class clazz = Class.forName("类全限定名");
2. Class clazz = 类名.class;
3. Class clazz = 对象.getClass();
3.2 常用方法
获取类信息方法签名
获取包名Package getPackage()
获取修饰符int getModifiers()
获取类简名String getSimpleName()
获取类全限定名String getName()
获取该类的类加载器ClassLoader getClassLoader()
返回直接实现的接口(由于编译擦除,没有显示泛型参数)Class[] getInterfaces()
返回直接继承的父类(由于编译擦除,没有显示泛型参数)ClassgetSuperclass()
返回直接实现的接口(包含泛型参数)Type[] getGenericInterfaces()
返回直接继承的父类(包含泛型参数)Type getGenericSuperclass()
获取public构造方法Constructor getConstructor(Class… parameterTypes)
获取所有public构造方法Constructor[] getConstructors()
获取public的方法Method getMethod(String name, Class… parameterTypes)
获取所有public的方法,包括父类Method[] getMethods()
获取public的属性Field getField(String name)
取所有public的属性Field[] getFields()
获取声明的构造方法Constructor getDeclaredConstructor(Class… parameterTypes)
获取所有声明的构造方法Constructor[] getDeclaredConstructors()
获取声明的方法Method getDeclaredMethod(String name, Class… parameterTypes)
获取所有声明的方法Method[] getDeclaredMethods()
获取声明的属性Field getDeclaredField(String name)
获取所有声明的属性Field[] getDeclaredFields()
3.3 父类 & 接口 信息
  • 不包含范型:
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("java.util.LinkedList");

        System.out.println(clazz.getSuperclass());

        System.out.println("----------------");

        Class[] classes = clazz.getInterfaces();

        for(Class c : classes){
            System.out.println(c);
        }
    }

    输出:
    class java.util.AbstractSequentialList
    ----------------
    interface java.util.List
    interface java.util.Deque
    interface java.lang.Cloneable
    interface java.io.Serializable  
  • 包含范型:
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("java.util.LinkedList");

        System.out.println(clazz.getGenericSuperclass());

        System.out.println("----------------");

        Type[] types = clazz.getGenericInterfaces();

        for (Type type : types) {
            System.out.println(type);
        }
    }

    输出:
    java.util.AbstractSequentialList<E>
    ----------------
    java.util.List<E>
    java.util.Deque<E>
    interface java.lang.Cloneable
    interface java.io.Serializable
3.4 Declared vs NonDeclared
  1. 带有Declared的方法,都是获取Class类中声明的方法或者属性
  2. 不带Declared的方法,都是获取Class类的public方法或者属性,包括继承自父类的方法或者属性

    • 构造方法:
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.Student");

        //获取public 构造方法
        Constructor[] constructors = clazz.getConstructors();

        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        System.out.println("----------------------");

        //获取所有构造方法
        Constructor[] constructors1 = clazz.getDeclaredConstructors();

        for (Constructor constructor : constructors1) {
            System.out.println(constructor);
        }
    }

    输出:
    public com.lilongjiu.study.reflection.Student(java.lang.String,java.lang.String)
    ----------------------
    public com.lilongjiu.study.reflection.Student(java.lang.String,java.lang.String)
    private com.lilongjiu.study.reflection.Student(java.lang.String)
  • 方法:
 public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.Student");

        //获取public方法,包括父类
        Method[] methods = clazz.getMethods();

        for (Method method : methods) {
            System.out.println(method);
        }

        System.out.println("----------------------");

        //获取所有方法,当前类声明的所有方法
        Method[] methods2 = clazz.getDeclaredMethods();

        for (Method method : methods2) {
            System.out.println(method);
        }
    }

    输出:
    public void com.lilongjiu.study.reflection.Student.attendClass()
    public java.lang.String com.lilongjiu.study.reflection.People.toString()
    public java.lang.String com.lilongjiu.study.reflection.People.getName()
    public void com.lilongjiu.study.reflection.People.sleep()
    public void com.lilongjiu.study.reflection.People.setName(java.lang.String)
    public java.lang.String com.lilongjiu.study.reflection.People.getId()
    public void com.lilongjiu.study.reflection.People.eat(java.lang.String)
    public void com.lilongjiu.study.reflection.People.setId(java.lang.String)
    public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
    public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
    public final void java.lang.Object.wait() 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 void com.lilongjiu.study.reflection.Student.attendClass()
    private void com.lilongjiu.study.reflection.Student.playGame()
3.3 类基本信息
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.People");

        //获取包名
        System.out.println(clazz.getPackage());

        //获取修饰符
        System.out.println(clazz.getModifiers());

        //获取类简名
        System.out.println(clazz.getSimpleName());

        //获取类全限定名
        System.out.println(clazz.getName());

        //获取该类的类加载器
        System.out.println(clazz.getClassLoader());

    }

    输出:
    package com.lilongjiu.study.reflection
    1
    People
    com.lilongjiu.study.reflection.People
    sun.misc.Launcher$AppClassLoader@1ddc4ec2
4. reflect 包

在java.lang.reflect包中有三个重要的类,这三个类分别表示:构造器,方法,属性。

  • Constructor
  • Method
  • Field
  • Modifier

5. Constructor

5.1 无参构造方法 & 实例化
  • 类有无参的构造方法
  • Class.newInstance()
  • Constructor.newInstance()
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.People");

        //Class.newInstance()
        People p1 = (People) clazz.newInstance();

        //Constructor.newInstance()
        Constructor constructor = clazz.getConstructor(null);
        People p2 = (People) constructor.newInstance();

        System.out.println(p1);
        System.out.println(p2);

    }

    输出:
    People{id='null', name='null'}
    People{id='null', name='null'}
5.1 带参数的构造方法 & 实例化
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.People");

        Constructor constructor = clazz.getConstructor(new Class[]{String.class, String.class});

        People people = (People) constructor.newInstance("123", "zhangsan");

        System.out.println(people);

    }

    输出:
    People{id='123', name='zhangsan'}
5.2 私有构造方法 & 实例化

访问私有方法一定要设置访问权限

  • Constructor.setAccessible(boolean flag)
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.People");

        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class});

        constructor.setAccessible(true);

        People people = (People) constructor.newInstance("zhangsan");

        System.out.println(people);

    }

    输出:
    People{id='null', name='zhangsan'}

6. Method

6.1 无参方法 & 调用
 public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.People");

        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, String.class});

        People people = (People) constructor.newInstance("123", "zhangsan");

        Method method = clazz.getMethod("sleep", null);

        method.invoke(people,null);
    }

    输出:
    zhangsan is sleeping

6.2 带参方法 & 调用

    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.People");

        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, String.class});

        People people = (People) constructor.newInstance("123", "zhangsan");

        Method method = clazz.getMethod("eat", new Class[] {String.class});

        method.invoke(people,"Apple");

    }

    输出:
    zhangsan is eating Apple

6.3 私有方法 & 调用

  • method.setAccessible(true);
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.People");

        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, String.class});

        People people = (People) constructor.newInstance("123", "zhangsan");

        Method method = clazz.getDeclaredMethod("study", new Class[] {String.class});

        method.setAccessible(true);

        method.invoke(people,"Java Reflection");

    }

    输出:
    zhangsan is studying Java Reflection

7. Field

7.1 类的字段
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("com.lilongjiu.study.reflection.People");

        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, String.class});

        People people = (People) constructor.newInstance("123", "zhangsan");

        Field field = clazz.getDeclaredField("name");

        field.setAccessible(true);

        //输出对象对应的属性值
        System.out.println(field.get(people));

        //输出属性类型
        System.out.println(field.getType());

    }

    输出:
    zhangsan
    class java.lang.String

8. Modifier

  • Class, Method, Field 都有 getModifiers 方法,其返回值是一个整数,Modifier可以根据这个整数判断对应的修饰符。
    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("java.util.List");

        Method method = clazz.getDeclaredMethod("add", new Class[]{Object.class});

        int modifiers = method.getModifiers();

        System.out.println(modifiers);
        System.out.println(Modifier.isPublic(modifiers));
        System.out.println(Modifier.isAbstract(modifiers));
        System.out.println(Modifier.isVolatile(modifiers));
        System.out.println(Modifier.isStatic(modifiers));
        System.out.println(Modifier.isFinal(modifiers));

    }

    输出:
    1025
    true
    true
    false
    false
    false
  • Modifier 定义了一些静态属性来表示public,abstract,static,final等修饰符
//非完整Modifer类
public class Modifier {
    public static final int PUBLIC = 1;
    public static final int PRIVATE = 2;
    public static final int PROTECTED = 4;
    public static final int STATIC = 8;
    public static final int FINAL = 16;
    public static final int SYNCHRONIZED = 32;
    public static final int VOLATILE = 64;
    public static final int TRANSIENT = 128;
    public static final int NATIVE = 256;
    public static final int INTERFACE = 512;
    public static final int ABSTRACT = 1024;
    public static final int STRICT = 2048;
    static final int BRIDGE = 64;
    static final int VARARGS = 128;
    static final int SYNTHETIC = 4096;
    static final int ANNOTATION = 8192;
    static final int ENUM = 16384;
    static final int MANDATED = 32768;
    private static final int CLASS_MODIFIERS = 3103;
    private static final int INTERFACE_MODIFIERS = 3087;
    private static final int CONSTRUCTOR_MODIFIERS = 7;
    private static final int METHOD_MODIFIERS = 3391;
    private static final int FIELD_MODIFIERS = 223;
    private static final int PARAMETER_MODIFIERS = 16;
    static final int ACCESS_MODIFIERS = 7;

    public Modifier() {
    }

    public static boolean isPublic(int var0) {
        return (var0 & 1) != 0;
    }

    public static boolean isPrivate(int var0) {
        return (var0 & 2) != 0;
    }

    public static boolean isProtected(int var0) {
        return (var0 & 4) != 0;
    }

    public static boolean isStatic(int var0) {
        return (var0 & 8) != 0;
    }

    public static boolean isFinal(int var0) {
        return (var0 & 16) != 0;
    }

    public static boolean isSynchronized(int var0) {
        return (var0 & 32) != 0;
    }

    public static boolean isVolatile(int var0) {
        return (var0 & 64) != 0;
    }

    public static boolean isTransient(int var0) {
        return (var0 & 128) != 0;
    }

    public static boolean isNative(int var0) {
        return (var0 & 256) != 0;
    }

    public static boolean isInterface(int var0) {
        return (var0 & 512) != 0;
    }

    public static boolean isAbstract(int var0) {
        return (var0 & 1024) != 0;
    }

    public static boolean isStrict(int var0) {
        return (var0 & 2048) != 0;
    }

    ...
}

9. Code

People类源码

package com.lilongjiu.study.reflection;

/**
 * Created by lilongjiu.
 */
public class People {

    private String id;

    private String name;

    public People() {

    }

    public People(String id, String name) {
        this.id = id;
        this.name = name;
    }

    private People(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public void eat(String food) {
        System.out.println(this.getName() + " is eating " + food);
    }

    private void study(String course) {
        System.out.println(this.getName() + " is studying " + course);
    }

    public void sleep() {
        System.out.println(this.getName() + " is sleeping");
    }

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


package com.lilongjiu.study.reflection;

/**
 * Created by lilongjiu.
 */
public class Student extends People{

    public String school;

    private String major;

    public Student(String id, String name){
        super(id, name);
    }

    private Student(String name){
        super(null, name);
    }

    public void attendClass(){
        System.out.println(this.getName() + " is atending class");
    }

    private void playGame(){
        System.out.println(this.getName() + " is playing game");
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值