java_web初学笔记之<java的反射机制>
来源:互联网 发布:mac maven 环境变量 编辑:程序博客网 时间:2024/06/07 09:48
首先明确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<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)方法: Field
getField(String name,);
返回此Class对象所表示的类的所有的(包括非public)方法: Field
getDeclaredField(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初学笔记之<java的反射机制>
- java_web初学笔记之<java编程规范>
- java_web初学笔记之<java注解>
- java_web初学笔记之<JavaBean及内省机制>
- java_web初学笔记之<BeanUtils工具包的用法>
- java_web初学笔记之<泛型的类型擦除>
- Java_web初学笔记之<泛型的目标类型推断>
- java_web初学笔记之<Tomcat服务器的简单配置>
- java_web初学笔记之<泛型基础>
- java_web初学笔记之<XML解析技术>
- java_web初学笔记之<Session与Cookie>
- Java初学习-Java的反射机制
- 初学java反射机制
- java_web初学笔记之<xml基础及约束>
- java_web初学笔记之<MyEclipse反编译jad插件配置>
- java_web初学笔记之<ServletConfig和ServletContext详解>
- java 反射机制初学习
- Java反射机制之数组的反射
- 常用正则表达式
- shell 脚本时,储命令返回的结果,用反引号即可
- linux基础教程(7)数据库操作与使用
- spring+动态代理
- 字符串删除数字大写变小写
- java_web初学笔记之<java的反射机制>
- 2015-第4周项目1-三角形类的构造函数
- Oracle中的ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
- jquery-1.8.3.min.js
- 【SICP练习】147 练习4.3
- linux gedit显示gbk字符
- C++中内存分配、函数调用和返回值问题
- spring-security错误记录(1)
- xmlHttp.open xmlHttp.responseText讨论