java反射机制浅析
2016-08-04 00:01
288 查看
本文主要是概念梳理,深入研究待续
程序运行时接收到外部传入的一个对象,该对象的编译类型是Object,如需要调用该对象运行类型的方法,若编译和运行都知道,使用instantof判断后强转即可,若编译时无法预知该对象属于什么类,程序只能靠运行时发现对象的真实信息,这就必须使用反射了
java程序中各个java类属于同一类事物,描述这类事物的类名就是Class,即字节码。
获取各个类的Class(字节码)有三种方式
1.类名.class
2.对象.getClass()
3.Class.forName(String className)静态方法,className表示全限定名;如String的全限定名:java.lang.String;
反射就是把java类中的各种成分映射成相应的java类,一个类中的组成部分,成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示。Java的Class类显然要提供一系列的方法,来获得其中的变量、方法、构造方法,修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们分别是 Filed Method Construct Package
构造方法的反射应用
Constructor类,
成员变量的反射
深入理解反射机制
JVM,java虚拟机,java之所以跨平台,就是因为它,可以理解秤一个进程,程序,作用是用来跑你的代码。
加入写了一段代码 Object=new Object(),首先JVM会启动,代码会变异成一个.class文件,创建了Object类的class文件对象到堆中,注意不是那new 出来的对象,而是类的类型对象,每个类只有一个class对象,作为方法区类的数据结构的接口。jvm创建对象之前,会检查类是否过载,寻找类对应的class对象,若加载好,则为你的对象分配内存,初始化也就是代码:new Object()。
当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到所以不用加载到jvm,而是在运行时根据需要才加载
反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
http://www.sczyh30.com/posts/Java/java-reflection-1/#%E4%B8%80%E3%80%81%E5%9B%9E%E9%A1%BE%EF%BC%9A%E4%BB%80%E4%B9%88%E6%98%AF%E5%8F%8D%E5%B0%84%EF%BC%9F
程序运行时接收到外部传入的一个对象,该对象的编译类型是Object,如需要调用该对象运行类型的方法,若编译和运行都知道,使用instantof判断后强转即可,若编译时无法预知该对象属于什么类,程序只能靠运行时发现对象的真实信息,这就必须使用反射了
java程序中各个java类属于同一类事物,描述这类事物的类名就是Class,即字节码。
获取各个类的Class(字节码)有三种方式
1.类名.class
2.对象.getClass()
3.Class.forName(String className)静态方法,className表示全限定名;如String的全限定名:java.lang.String;
反射就是把java类中的各种成分映射成相应的java类,一个类中的组成部分,成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示。Java的Class类显然要提供一系列的方法,来获得其中的变量、方法、构造方法,修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们分别是 Filed Method Construct Package
构造方法的反射应用
Constructor类,
//得到全部构造器 Constructor<?>[] constructors = Person.class.getConstructors(); //得到指定构造器,必须将构造器参数传入 try { Constructor constructor =Person.class.getConstructor(String.class, int.class); } catch (NoSuchMethodException e) { e.printStackTrace(); }
成员变量的反射
Person person = new Person(); Field[] fields = person.getClass().getFields(); try { Field nameField = person.getClass().getField("name"); String name = (String) nameField.get(person); } catch (Exception e) { e.printStackTrace(); }
/** * 所有的String 成员变量都只截取前六位 * @param obj */ public void changeFild(Object obj) { Field[] declaredFields = obj.getClass().getDeclaredFields(); for (Field field:declaredFields){ field.setAccessible(true);//设置成员变量可访问(暴力反射) if (field.getType()==String.class){ try { String str= (String) field.get(obj);//读取成员变量的值 String substring = str.substring(0, 6); field.set(obj,substring);//重新设置成员变量的值 } catch (IllegalAccessException e) { e.printStackTrace(); } } } }
try { Constructor<Person> constructor = Person.class.getConstructor(String.class, int.class); Person peron = constructor.newInstance("zhangsan", 16); Method method = person.getClass().getMethod("setName",String.class); method.invoke(person,"zhangsna"); } catch (Exception e) { e.printStackTrace(); }
深入理解反射机制
JVM,java虚拟机,java之所以跨平台,就是因为它,可以理解秤一个进程,程序,作用是用来跑你的代码。
加入写了一段代码 Object=new Object(),首先JVM会启动,代码会变异成一个.class文件,创建了Object类的class文件对象到堆中,注意不是那new 出来的对象,而是类的类型对象,每个类只有一个class对象,作为方法区类的数据结构的接口。jvm创建对象之前,会检查类是否过载,寻找类对应的class对象,若加载好,则为你的对象分配内存,初始化也就是代码:new Object()。
当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到所以不用加载到jvm,而是在运行时根据需要才加载
反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
http://www.sczyh30.com/posts/Java/java-reflection-1/#%E4%B8%80%E3%80%81%E5%9B%9E%E9%A1%BE%EF%BC%9A%E4%BB%80%E4%B9%88%E6%98%AF%E5%8F%8D%E5%B0%84%EF%BC%9F