您的位置:首页 > 编程语言 > Java开发

JAVA反射机制详解

2011-07-25 16:39 495 查看
3.4 . 通过Class类取得完整结构(了解)
通过Class类中的很多方法,可以轻易得取得一个类中定义的全部构造方法,普通方法,常量,变量等等.例如: 现在假设有如下的类:
package org.lxh.demo.classdemo04;
interface Info{
public static final String AUTHOR = "MICHELE";
public String getInfo();
public String say(String name,String content);
public void sayHello();
}
public class Person implements Info{
private String name;
private int age;
public Person(){
}
public String getInfo() {
return "getInfo is hello world !";
}
public String say(String name, String content) {
return name + "说了:" + content;
}
public void sayHello() {
System.out.println("hello --> " + AUTHOR);
}
public Person(String name ){
this.setName(name);
}
public Person(String name , int age){
this(name);
this.setAge(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "姓名:" + this.name + "; 年龄:" + this.age;
}
}
下面通过一系列的反射, 完成操作.

3.4.1 . 取得继承的父类
在Class类中存在以下的方法, 可以取得一个继承的父类:
public Class<? super T> getSuperclass()

范例: 取得父类.
package org.lxh.demo.classdemo04;
public class GetSuperClassDemo {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");
Class<?> sc = c.getSuperclass();
System.out.println(sc.getName());
}
}
此时Person类没有继承任何父类,所以其父类就是Object类.

3.4.2 . 取得实现的全部接口
一个类中可以实现多个接口,所以在Class类中提供了以下方法:
public Class<?>[] getInterfaces()
接口本身就是一个特殊的类, 所以会以Class的对象数组形式返回.
package org.lxh.demo.classdemo04;
public class GetInterfacesDemo {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");
Class<?> inter[] = c.getInterfaces();//得到全部接口
for(int i = 0 ; i < inter.length ; i++){
System.out.println(inter[i].getName());//输出全部接口内容
}
}
}

3.4.3 . 取得一个类的全部构造方法
之前已经演示过如何取得一个类的构造方法
public Constructor<?>[] getConstructors() throws SecurityException

在Person类中定义了三个构造方法,那么此时可以全 部取出
package org.lxh.demo.classdemo04;
import java.lang.reflect.Constructor;
public class GetConstructorDemo01 {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");
Constructor<?> con[] = c.getConstructors();//得到全部构造
for(int i = 0 ; i < con.length ; i++){
System.out.println(con[i]);//输出全部构造内容
}
}
}
以上确实得到了全部的构造方法,但是程序有一个弊病,是通过toString()自动输出的.如果现在直接通过getName()方法取得,则只能取得构造方法的名字,而访问的修饰符和参数完全不见,所以,如果现在想手工拼凑出一个完整的构造方法,还需要以下的几个方法支持:
得到访问修饰符: public int getModifiers()
得到全部的参数: public Class<?> getParameterTypes()
package org.lxh.demo.classdemo04;
import java.lang.reflect.Constructor;
public class GetConstructorDemo01 {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");
Constructor<?> con[] = c.getConstructors();//得到全部构造
for(int i = 0 ; i < con.length ; i++){
int mod = con[i].getModifiers();//得到修饰符
Class<?> param[] = con[i].getParameterTypes();
System.out.print(mod + " ");
System.out.print(con[i].getName() + " (");//输出全部构造内容
for(int x = 0 ; x < param.length ; x++){
System.out.print(param[x].getName() + "arg-" + x);
if(x == param.length - 1)
{
System.out.print(",");
}
}
System.out.println(")");
}
}
}
此时的程序输出如下:
1 org.lxh.demo.classdemo04.Person (java.lang.Stringarg-0intarg-1,)
1 org.lxh.demo.classdemo04.Person (java.lang.Stringarg-0,)
1 org.lxh.demo.classdemo04.Person ()
从结果中可以发现, 访问修饰符是数字, 并还是之前的public, 在实际的开发中所有的访问权限
基本上都是以数字的形式表示出来的,这样程序会比较好写,对于public,private而言, 本身也是对应
的一个数字. 而且对于public static final,实际上是属于三个值相加的结果, 所以,如果要想正确地还原一个方法的访问修饰符,则必须使用一个Modifer(java.lang.reflect)的类进行还原.
Public static string toString(int mod)
通过以上的方式可以还原修饰符:
package org.lxh.demo.classdemo04;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class GetConstructorDemo03 {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");
Constructor<?> con[] = c.getConstructors();//得到全部构造
for(int i = 0 ; i < con.length ; i++){
int mod = con[i].getModifiers();//得到修饰符
String str = Modifier.toString(mod);//还原权限
Class<?> param[] = con[i].getParameterTypes();
System.out.print(str + " ");//访问修饰符(单词表示)
System.out.print(con[i].getName() + " (");//输出全部构造内容
for(int x = 0 ; x < param.length ; x++){
System.out.print(param[x].getName() + "arg-" + x);
if(x == param.length - 1)
{
System.out.print(",");
}
}
System.out.println(")");
}
}
}
Myeclipse 的智能提示也是运用以上的方法拼凑出来的



3.4.4 . 取得一个类的全部方法
在Class 类中定义了以下的方法,通过此方法可以取得一个类中的全部方法:
public Method[] getMethods() throws SecurityException
范例: 得到Person类的全部方法
package org.lxh.demo.classdemo04;
import java.lang.reflect.Method;
public class GetMethodDemo {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");
Method m[] = c.getMethods(); //得到全部的方法
for(int i = 0 ; i < m.length ; i++){
System.out.println(m[i]);//输出全部构造内容
}
}
}
以上是取得一个类中全部方法的操作, 是目前最方便的.
但是与构造方法一样, 也可以通过反射机制慢慢取得.此时需要以下方法的支持:
?取得方法的返回值类型: public Class<?> getReturnType()
?取得方法的全部参数:public Class<?>[] getParameterTypes()
?取得方法的抛出异常: public Class<?>[] getExceptionTypes()
package org.lxh.demo.classdemo04;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class GetMethodDemo2 {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");
Method m[] = c.getMethods(); //得到全部的方法
for(int i = 0 ; i < m.length ; i++){
String mod = Modifier.toString(m[i].getModifiers());//取得访问权限
String metName = m[i].getName();//方法名称
Class<?> ret = m[i].getReturnType();//返回值类型
Class<?> param[] = m[i].getParameterTypes();//全部的参数类型
Class<?> exc[] = m[i].getExceptionTypes();//全部异常
System.out.print(mod + " ");
System.out.print(ret + " ");
System.out.print(metName + " (");
for(int x = 0 ; x < param.length ;x++){
System.out.print(param[x] + "arg-" + x);
if(x < param.length - 1){
System.out.print(",");
}
}
System.out.print(")");
if(exc.length > 0){
System.out.print("throws ");
for(int x = 0 ; x < exc.length ;x++){
System.out.print(exc[x].getName());
if(x < exc.length - 1){
System.out.print(",");
}
}
}
System.out.println();
}
}
}

3.4.5 . 取得一个类的全部属性
Class 类中定义的可以取得一类中全部属性的方法:

?得到继承而来的公共属性:public Field[] getFields() throws SecurityException
?得到自定义的属性: public Field[] GetDeclaredFields() throws SecurityException
package org.lxh.demo.classdemo04;
import java.lang.reflect.Modifier;
import java.lang.reflect.Field;
public class GetFieldsDemo01 {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo04.Person");
{
Field f[] = c.getFields();//得到全部变量
for(int i = 0 ; i < f.length ; i++){
String mod = Modifier.toString(f[i].getModifiers());
System.out.print(mod + " ");
System.out.print(f[i].getType().getName());

}
}
System.out.println();
{
Field f[] = c.getDeclaredFields();//得到全部变量
for(int i = 0 ; i < f.length ; i++){
String mod = Modifier.toString(f[i].getModifiers());
System.out.print(mod + " ");
System.out.println(f[i].getType().getName());

}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: