Java高级特性反射概述及常用方法总结

一、反射的概述


JAVA反射机制是在运行状态中,对于任意一个,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想分析一个类,必须先要获取到该类的字节码文件对象。而分析使用的就是Class类中的方法.所以先要获取到字节码文件对应的Class类型的对象.

如图所示演示了反射的整个过程(画了很久的图,我认为描述清楚了)

 

接下来用代码记录反射的常用方法:

先建立两个接口(后面有用):

MyInterface.java

public interface MyInterface {
    void interfaceMethod();
}

MyInterface2.java

public interface MyInterface2 {
    void interfaceMethod();
}

再创建一个学生类,属性为id,姓名和性别,并实现有参构造方法,无参构造方法,静态方法。

Student.java

public class Student implements MyInterface {
    private int id;
    private String name;
    public String sex;

    public Student() {
    }

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

    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 static void staticmethon(){  //静态方法
        System.out.println("static methods..");
    }

    @Override
    public void interfaceMethod() {//实现MyInterface接口
        System.out.println("interfaceMethon");
    }
}

 

二、反射常用方法

1、Class.forName()方法(本文剩余的方法介绍都得先用这个方法获取反射入口)

最重要的是先获取反射入口Class对象(有三种方式),但这里用最普遍的Class.forName()方法,注意要写上抛出ClassNotFoundException异常

ReflectDemo.java

public class ReflectDemo {
    public static void main(String[]args) throws ClassNotFoundException {
        Class<?> refelct=Class.forName("Student");//获取反射入口,注意forName内要写完整的类路径
        System.out.println(refelct);
    }
}

 

2、通过反射获取类的公共方法(本类,父类和接口的非private方法)

refelect.getMethods():返回Method数组

import java.lang.reflect.Method;

public class ReflectDemo {
    public static void main(String[]args) throws ClassNotFoundException {
        Class<?> refelct=Class.forName("Student");
        Method[] methods=refelct.getMethods();
        for(Method method:methods){
            System.out.println(method);
        }
    }
}

输出结果:

拿到了包括当前类其父类Object类的所有公共方法以及实现了接口的方法interfaceMethon()

就拿第一个public java.lang.String Student.getName() 和Student.java中的public String getName()相比,显然通过反射拿到的是很完整的

 

3、通过反射获取本类的所有非private修饰的方法(本类的所有方法,不包括父类,但包括接口)

refelect.getDeclaredMethods():返回Method数组

import java.lang.reflect.Method;

public class ReflectDemo {
    public static void main(String[]args) throws ClassNotFoundException {
        Class<?> refelct=Class.forName("Student");
        Method[] methods=refelct.getDeclaredMethods();
        for(Method method:methods){
            System.out.println(method);
        }
    }
}

输出结果:

最后一行是接口

 

4、通过反射获取类的接口

reflect.getInterfaces():返回接口名数组

public class ReflectDemo {
    public static void main(String[]args) throws ClassNotFoundException {
        Class<?> refelct=Class.forName("Student");
        Class<?>[]interfaces=refelct.getInterfaces();
        for(Class<?> inter:interfaces){
            System.out.println(inter);
        }
    }
}

输出结果:

 

5、通过反射获取类的父类

refelct.getSuperclass():返回父类

由于java是单继承,所以返回值不是数组

public class ReflectDemo {
    public static void main(String[]args) throws ClassNotFoundException {
        Class<?> refelct=Class.forName("Student");
        Class<?>superclass=refelct.getSuperclass();
            System.out.println(superclass);
        }
}

输出结果:

任何一个类都继承Object类,所以会输出Object类

 

6、通过反射获取类的所有构造方法 

refelct.getConstructors():返回类所有构造方法,返回值为数组
import java.lang.reflect.Constructor;

public class ReflectDemo {
    public static void main(String[]args) throws ClassNotFoundException {
        Class<?> refelct=Class.forName("Student");
        Constructor<?>[] constructors=refelct.getConstructors();
            for (Constructor<?> constructor:constructors){
                System.out.println(constructor);
            }
        }
}

输出结果:一个无参构造,一个有参构造 

 

 

 7、通过反射获取类的所有公共属性(不包括Private修饰的属性)

 refelct.getFields():返回Field类型数组

import java.lang.reflect.Field;

public class ReflectDemo {
    public static void main(String[]args) throws ClassNotFoundException {
        Class<?> refelct=Class.forName("Student");
        Field[] fields=refelct.getFields();
            for (Field field:fields){
                System.out.println(field);
            }
        }
}

输出结果:(注意private修饰的属性无法拿到,代码中studnet的id和name都是private因此没有输出,只输出了public修饰的sex属性)

 

 

 8、通过反射获取本类所有属性(包括Private修饰的属性,不包括父类和父接口)

 refelct.getDeclaredFields():返回Field类型数组

import java.lang.reflect.Field;

public class ReflectDemo {
    public static void main(String[]args) throws ClassNotFoundException {
        Class<?> refelct=Class.forName("Student");
        Field[] fields=refelct.getDeclaredFields();
            for (Field field:fields){
                System.out.println(field);
            }
        }
}

 输出结果:

很明显private的属性id和name都输出了

 

9、 通过反射获取类的实例对象(和普通的new一个对象功能类似)

refelct.newInstance();

需要设置可能会抛出的两个异常:IllegalAccessException, InstantiationException

public class ReflectDemo {
    public static void main(String[]args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class<?> refelct=Class.forName("Student");
        Object student=refelct.newInstance();//获得的是个Object类对象
        Student student1=(Student)student;//将Object对象向下转型为Student类对象
        student1.interfaceMethod();//验证:通过调用Student类的静态方法打印输出
        }
    }

输出内容: 

可以看出这种方法和使用Student student=new student();student.interfaceMethod();起到了相同的效果

 

                                                                                                                                                                                                                                                                                End...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值