java高级特性:反射

java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的他、任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

比如说,有一段程序已经写好了,其他的程序是后写的,从原则上来讲不可能调用后写的东西,用传统的方法是调用不到的,但是还有一个方法就是在运行的时候扫描字节码,我们知道字节码对类来讲有属性和方法,它扫描到字节码里面定义的属性和方法。然后假设我们知道方法名,它只要符合规范,我们知道字节码里面有这个东西,就能动态调用这个方法。这也叫运行期绑定,在运行的时候去绑定。传统的编码是一次性将所有方法编到一块,在我们编译的时候谁调谁已经预定好了。

反射机制在运行的时候有个类加载机制,在运行期扫描类的字节码,扫描完之后加载到虚拟机之中,程序可以将这些封装成一个描述类的类。

类:字节码

1、属性  2、方法 3、构造 4、基类  5、接口、、、、、、、、、、、、

拿到字节码就能拿到这些信息,但是我们不认识字节码,但是虚拟能认识字节码,它将类封装成了一个类,在这个类中有属性对象的集合,方法的集合等。

package reflect;
        /*反射*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Date;

public class MainClass {
    public static void main(String[] args) throws Exception {
        String className = "java.util.Date";
        /*forname方法:
         * 1、根据类名在类路路径中查找有没有这个类名的.class文件
         * 2、如果在类路径中找到这个字节码文件,则会经过查找加载到虚拟机当中。
         * 3、在扫描检查的过程中,虚拟机还会得到是不是字节码中定义的内容(属性、方法等信息),则
         * forName方法会实例一个class对象,把检查到的字节码信息存入Class对象中
         * 4、我们通过Class对象,可以以一种比较友好的方式,得字节码中的信息
         * */
        Class c = Class.forName(className);
        System.out.println(c.getName());
        Field[] fs = c.getDeclaredFields();
        for (Field f : fs) {
            System.out.println(f.getName() + ":" + f.getType().getName());
        }
        Method[] methods = c.getMethods();
        for (Method m : methods) {
            System.out.println(m.getName() + ":" + m.getReturnType().getName());
            Parameter[] ps = m.getParameters();
            for (Parameter p : ps) {
                System.out.println("    " + p.getName() + ":" + p.getType().getName());
            }
        }
        Constructor[] ccs = c.getConstructors();
        for (Constructor cc : ccs) {
            System.out.println(cc.getParameterCount());
        }
        /*硬编码 前期绑定*/
        Date d = new Date();
        //后期绑定
        Object o = ccs[2].newInstance();
        System.out.println(o);
        //下标为2的是默认参数的构造函数
        //方法反射出来时调用的,构造反射出来是实例化对象的。
        Method[] methods1 = c.getMethods();
        for (Method m : methods1) {
            System.out.println(m.getName() + ":" + m.getReturnType());
            if ("setYear".equals(m.getName())) {
                m.invoke(o, 2018);
                System.out.println("定义时间:");

            }
            Parameter[] ps = m.getParameters();
            for (Parameter p : ps) {
                System.out.println("    " + p.getName() + ":" + p.getType().getName());

            }

        }

    }

}




    /*public Class<?> getType() {
        Class<?> tmp = parameterClassCache;
        if (null == tmp) {
            tmp = executable.getParameterTypes()[index];
            parameterClassCache = tmp;
        }
        return tmp;
    }
*/


    /*public String getName() {
        String name = this.name;
        if (name == null)
            this.name = name = getName0();
        return name;
    }*/



发布了64 篇原创文章 · 获赞 47 · 访问量 9549

猜你喜欢

转载自blog.csdn.net/weixin_42194284/article/details/100070863