java_web初学笔记之<java的反射机制>
2015-03-29 19:33
911 查看
首先明确java类中有什么信息?
①构造方法(构造器)Constructor
②属性(也成为字段)Field
③方法 Method
④包名
⑤修饰符...等信息
①②③这几个每一个都有public和非public之分。
Class类代表java类,一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这个一个个的空间可分别用一个个的对象来表示。
Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件即字节码文件(.class文件)从硬盘读取到内存中。类装载方式有两种:①隐式装载,程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中。②显示装载,通过class.forname()等方法,显式加载需要的类(这就是反射里要用到的)。类装载完以后需要解析字节码文件,解析完以后,在JVM中都有一个对应的java.lang.Class对象,提供了类结构信息的描述,此时才能操作所有的信息。数组,枚举及基本数据类型,甚至void都拥有对应的Class对象。Class类没有public的构造方法,Class对象是在装载类时由JVM通过调用类装载器中的defineClass()方法自动构造的。
具体看下面的图:
接着来了解一下反射,那么何为反射呢?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法(包括构造方法);对于任意一个对象,都能够调用它的任意一个方法和属性(不管public或者非public);这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
☆☆☆反射就是把Java类中的各种成分映射成一个个的java对象,反射就像解剖,把一个类中的所有成分都映射为一个个的对象,直接可以操作它们。
—————————————————————————————————————————————————————————
—————————————————————————————————————————————————————————
Class是Reflection故事起源。针对任何您想探勘的类,唯有先为它产生一个Class 对象,接下来才能经由后者(即Class对象,因为是要解剖类Class的,所以要现有Class对象,这样才可以解剖)唤起为数十多个的Reflection API(即Class对象的大部分方法返回的都是java.lang.reflect包下的类,如Field,Method,Constructor等类)
获取Class类对象的方法:
①类名.class 将被建模的类在编译时即可知,比如String.class 返回的是Class<String>
②对象.getClass() 将被建模的类在编译时即可知,比如"abc".getClass()返回的是Class<? extends String> 即返回的是String类或其子类(看?是什么返回的就是什么)
③Class.forName(String className) 一般推荐使用该方法
—————————————————————————————————————————————————————————
—————————————————————————————————————————————————————————
Class对象的方法(用于解剖):(一个类被封装在Class对象中,类中的方法,构造方法,成员变量都被封装在该Class对象的成员变量或方法中)
①返回Constructor类对象的:(它有泛型)
返回此
返回此Class对象所表示的类的所有的(包括非public)构造方法:
②返回Method类型对象的:
返回此
name, Class<?>... parameterTypes);
name - 方法名parameterTypes - 参数类型数组
返回此Class对象所表示的类的所有的(包括非public)方法:Method getDeclaredMethod(String name, Class<?>... parameterTypes);
③返回Field类型对象的:
返回此
name,);
返回此Class对象所表示的类的所有的(包括非public)方法:
name);
......还有很多其他方法,需要时可以查阅JDK API 1.6
public方法和非public方法的区别在于get后面多一个Declared。
java.lang.reflect包下的类:
Constructor<T>类:
T newInstance(Object... initargs);使用此
其他方法用到时看JDK API 1.6
Method类:
其他方法用到时看JDK API 1.6
Field类:
其他方法用到时看JDK API 1.6
这些类都继承于AccessibleObject 类,该类有一个方法在访问非public成员时会用到。
综上,使用反射的步骤为:
①获取Class对象,大部分都通过Class.forName(String name);获取,有泛型
②通过Class对象得到java.lang.reflect包下的类的对象,如ConStructor 对象 con
③如果是非public的,设置可访问性。如con.setAccessible(true);
④调用java.lang.reflect包下的类的对象的方法。如con.newInstance();
注意有时候需要向下转型,因为有些返回的是Object类型。
示例代码:
Student类
①构造方法(构造器)Constructor
②属性(也成为字段)Field
③方法 Method
④包名
⑤修饰符...等信息
①②③这几个每一个都有public和非public之分。
Class类代表java类,一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这个一个个的空间可分别用一个个的对象来表示。
Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件即字节码文件(.class文件)从硬盘读取到内存中。类装载方式有两种:①隐式装载,程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中。②显示装载,通过class.forname()等方法,显式加载需要的类(这就是反射里要用到的)。类装载完以后需要解析字节码文件,解析完以后,在JVM中都有一个对应的java.lang.Class对象,提供了类结构信息的描述,此时才能操作所有的信息。数组,枚举及基本数据类型,甚至void都拥有对应的Class对象。Class类没有public的构造方法,Class对象是在装载类时由JVM通过调用类装载器中的defineClass()方法自动构造的。
具体看下面的图:
接着来了解一下反射,那么何为反射呢?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法(包括构造方法);对于任意一个对象,都能够调用它的任意一个方法和属性(不管public或者非public);这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
☆☆☆反射就是把Java类中的各种成分映射成一个个的java对象,反射就像解剖,把一个类中的所有成分都映射为一个个的对象,直接可以操作它们。
—————————————————————————————————————————————————————————
—————————————————————————————————————————————————————————
Class是Reflection故事起源。针对任何您想探勘的类,唯有先为它产生一个Class 对象,接下来才能经由后者(即Class对象,因为是要解剖类Class的,所以要现有Class对象,这样才可以解剖)唤起为数十多个的Reflection API(即Class对象的大部分方法返回的都是java.lang.reflect包下的类,如Field,Method,Constructor等类)
Class<T>类:T- 由此
Class对象建模的类的类型。例如,
String.class的类型是
Class<String>。如果将被建模的类未知,则使用
Class<?>。
获取Class类对象的方法:
①类名.class 将被建模的类在编译时即可知,比如String.class 返回的是Class<String>
②对象.getClass() 将被建模的类在编译时即可知,比如"abc".getClass()返回的是Class<? extends String> 即返回的是String类或其子类(看?是什么返回的就是什么)
③Class.forName(String className) 一般推荐使用该方法
Class类中有一个静态方法:public static Class<?> forName(String className)
返回的类未知,因为只有运行的时候才能知道,所以在定义的时候是Class<?> c = Class.forName("java.lang.String");
—————————————————————————————————————————————————————————
—————————————————————————————————————————————————————————
Class对象的方法(用于解剖):(一个类被封装在Class对象中,类中的方法,构造方法,成员变量都被封装在该Class对象的成员变量或方法中)
①返回Constructor类对象的:(它有泛型)
返回此
Class对象所表示的类的指定公共(public)构造方法:
Constructor<T>getConstructor(Class<?>... parameterTypes);
返回此Class对象所表示的类的所有的(包括非public)构造方法:
Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes);
②返回Method类型对象的:
返回此
Class对象所表示的类的指定公共(public)方法: Method getMethod(String
name, Class<?>... parameterTypes);
name - 方法名parameterTypes - 参数类型数组
返回此Class对象所表示的类的所有的(包括非public)方法:Method getDeclaredMethod(String name, Class<?>... parameterTypes);
③返回Field类型对象的:
返回此
Class对象所表示的类的指定公共(public)方法:
FieldgetField(String
name,);
返回此Class对象所表示的类的所有的(包括非public)方法:
FieldgetDeclaredField(String
name);
......还有很多其他方法,需要时可以查阅JDK API 1.6
public方法和非public方法的区别在于get后面多一个Declared。
java.lang.reflect包下的类:
Constructor<T>类:
T- 在其中声明构造方法的类。
T newInstance(Object... initargs);使用此
Constructor对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数initargs初始化该实例。
其他方法用到时看JDK API 1.6
Method类:
Objectinvoke(Object obj,Object... args)对带有指定参数的指定对象调用由此
Method对象表示的底层方法。
其他方法用到时看JDK API 1.6
Field类:
void set(Object obj,Object value)将指定对象变量上此
Field对象表示的字段设置为指定的新值。
其他方法用到时看JDK API 1.6
这些类都继承于AccessibleObject 类,该类有一个方法在访问非public成员时会用到。
setAccessible(boolean flag)将此对象的accessible 标志设置为指示的布尔值。当flag置true,表示可访问非public成员,否则不可以访问。即在访问非public之前必须由反射对象设置可访问性,对于public的可以不设置。默认flag为false。
综上,使用反射的步骤为:
①获取Class对象,大部分都通过Class.forName(String name);获取,有泛型
②通过Class对象得到java.lang.reflect包下的类的对象,如ConStructor 对象 con
③如果是非public的,设置可访问性。如con.setAccessible(true);
④调用java.lang.reflect包下的类的对象的方法。如con.newInstance();
注意有时候需要向下转型,因为有些返回的是Object类型。
示例代码:
<span style="font-size:14px;">package com.qq.java.reflect; import java.lang.reflect.Constructor; public class ReflectDemo2 { public static void main(String[] args) throws Exception { /*//获取Class对象,该对象提供了类结构的信息 <span style="white-space:pre"> </span>Class<?> c = Class.forName("com.qq.java.reflect.Student"); <span style="white-space:pre"> </span>//通过Class对象获取Constructor对象,如果构造方法无参数,则不用写 <span style="white-space:pre"> </span>Constructor<?> con = c.getConstructor(); <span style="white-space:pre"> </span>//调用反射对象的方法,通过构造方法对象的newInstance方法获取创建对象 <span style="white-space:pre"> </span>Student s = (Student) con.newInstance(); <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>s.show(); 这个是创建了对象后调用的,不推荐*/ <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>Class<?> c = Class.forName("com.qq.java.reflect.Student"); <span style="white-space:pre"> </span>Constructor<?> con = c.getDeclaredConstructor(String.class); <span style="white-space:pre"> </span>con.setAccessible(true); <span style="white-space:pre"> </span>Student stu = (Student)con.newInstance("Rose"); <span style="white-space:pre"> </span>Field f = c.getDeclaredField("name"); <span style="white-space:pre"> </span>f.setAccessible(true); <span style="white-space:pre"> </span>f.set(stu, "Jack"); <span style="white-space:pre"> </span>Method m = c.getDeclaredMethod("show");//如果方法没有参数,则不写,均不要写null <span style="white-space:pre"> </span>m.setAccessible(true); <span style="white-space:pre"> </span>m.invoke(stu); } } </span>
Student类
<span style="font-size:14px;">package com.qq.java.reflect; public class Student { private String name; private Student(String name) { this.name = name; System.out.println("Student constructor"+":"+name); } public String getName() { return name; } public void setName(String name) { this.name = name; } private void show() { System.out.println("I love java "+name); } }</span>
相关文章推荐
- java_web初学笔记之<JavaBean及内省机制>
- java_web初学笔记之<Tomcat服务器的简单配置>
- java_web初学笔记之<Jsp四个域对象page/request/session/application>
- java_web初学笔记之<泛型基础>
- Java_web初学笔记之<MyEclipse自动提示设置 空格和等号不补全>
- java_web初学笔记之<xml基础及约束>
- java_web初学笔记之<java注解>
- java_web初学笔记之<BeanUtils工具包的用法>
- java_web初学笔记之<Servlet中的request和response对象详解>
- java_web初学笔记之<Session与Cookie>
- java_web初学笔记之<MyEclipse反编译jad插件配置>
- java_web初学笔记之<ServletConfig和ServletContext详解>
- java_web初学笔记之<XML解析技术>
- Java_web初学笔记之<泛型的目标类型推断>
- java_web初学笔记之<java编程规范>
- java_web初学笔记之<泛型的类型擦除>
- java初学笔记之<this关键字在内部类的注意点>
- java初学笔记之<Random详解>
- [原]java专业程序代写(qq:928900200),学习笔记之基础入门<反射>(二十九)
- Java学习笔记之<反射、内省、BeanUtils包操作JavaBean的对比>