今天复习了Java的反射机制,说实话,对于这方面的知识自己以前只是了解一点,并没有透彻的研究理解过,今天通过听张老师的视频,对java反射机制有了整体上的一个理解,反射就是把java中的各种成分映射成各种java类(真是类外有类啊),
java反射机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Serializable),也包括fields和methods的所有信息,并可于运行时改变fields内容或调用methods。
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中
Class类:代表一个类。
Constructor 类:代表类的构造方法。
Field 类:代表类的成员变量(成员变量也称为类的属性)。
Method类:代表类的方法。
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
一、Class类 ( Class类,反射的基石,)
Class类是Reflection API 中的核心类,它有以下方法
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性,
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数 指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
二、Constructor类
1、获得某个类的所有构造方法:Constructor[] constructors = Class.forName("java.lang.String").getConstructors();
2、获得某个类的某个构造方法:Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);//获得构造方法时要指明参数类型,注意,在编译阶段编译器并不知道constructor是谁的构造方法,只有到程序运行时才知道是String的构造方法。
3、创建实例对象方式有两种:
常用方式:String str = new String(new StringBuffer("itcast"));
反射方式:String str = (String)constructor.newInstance(new StringBuffer("heima"));//注意要强制类型转换,另外注意传递参数的一致性,即得到构造方法的参数类型与实例化构造方法的参数类型要一致,若将上述方式改成这样,String str = (String)construtor.newInstance("CSDN");这样的话,编译期虽然能够通过,但是运行时会报类型不匹配的异常。
三、Filed类
public class Point{
private int x;
public int y;
............这里为xy的构造方法
}
public class TestReflect{
............只写了相关代码,部分代码省略
Point p = new Point(12,3);
Field fieldY = p.getClass().getField("y");
System.out.println(fieldY.get(p));//打印出来应该为12,
System.out.println(fieldY);//打印出来为变量的定义,我这里是 public int com.itcast.Test.Point.y
Field fieldX = p.getClass.getDeclaredField("x");//因为x声明为私有变量,要用getDeclaredField(type arg)才能拿到,
fieldX.setAccessible(true);//由于x为私有变量,对上面拿到的fieldX还要进行设置可访问后才能够用,这也叫暴力反射
System.out.println(fieldX.get(p));
............
}
注意fieldY不是对象p上的变量,而是代表字节码文件上的一个变量,所以取变量x的值应该到对象p上去取,如fieldY.get(p)
四、 Method类
Class.getMethod方法的时候接受哪些参数?显然要一个方法名,可以是同名的方法有多个,这又怎么识别出哪一个呢?这就需要靠参数类型和参数个数了。参数类型用什么来表示啊?用Class,例如,int.class,String.class等
Method.invoke()接受哪些参数,如果一个参数为null,表示的是调用这个方法不需要对象,从侧面说明了是静态方法!
题目:要你写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。
public class TestReflect{
..........部分代码略
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
//mainMethod.invoke(null, new Object[]{new String[]{"a","b","c"}});
mainMethod.invoke(null, (Object)new String[]{"a","b","c"});
...........
class TestArguments{
public static void main(String[] args){
for(String arg : args){
System.out.println(arg);
}
.............
}
}因为方法的重载,main方法可能会有多个,到底选哪一个呢?getMethod("main", args);中的第二个参数,就是指定要选择的那个main方法的参数类型,根据参数类型与个数,Method就知道去调用哪一个main方法了。
由于我们知道main方法的参数是String [] args,所以,String[].class来表示他的类型,mainMethod.invoke(null, (Object)new String[]{"a","b","c"});中的第一个参数是null,不是一个对象,那说明不用对象即调用这个方法,那么,这个方法应该是静态方法,第二个参数,就是传递给main方法的参数。
在给main方法传递参数时,不能使用如下代码mainMethod.invoke(null, new new String[]{"a","b","c"}});虽然这符合jdk1.5的语言要求,但是,jdk把它理解成了jdk1.4,对这个String数组进行了拆包,所以,出现了参数类型不对的问题。对于传数组的情况,只能按jdk1.4的语法进行调用,因为如果参数类型就是Object,它是没有办法区别的。
五、Array类
Array工具类用于完成对数组的反射操作
public class TestReflect{
........
public static void main(String[] args){
....
String [] a1 = new String[]{"a","b","c"};
printObject(a1);
printObject("abc");
....
}
private static void printObject(Object obj) {
Class clazz = obj.getClass();
if(clazz.isArray()){ //判断传入的对象是不是数组,
int len = Array.getLength(obj); //利用反射工具类Array得到数组的长度
for(int i=0;i<len;i++){ //循环遍历数组
System.out.println(Array.get(obj, i)); //拿到数组的第i个值。
}
}else{
System.out.println(obj);
}
......
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lganggang131/archive/2010/12/28/6103893.aspx
发表评论
-
java web开发之Servlet
2011-03-16 23:49 927尽管还有许多烦心的事 ... -
OXM(Object XML Mapping)技术——JAXB实现对象与XML之间的相互转换
2011-03-15 00:23 1179今天上午接着昨天的内容继续讲解XML相关的技术,重点讲解了JA ... -
GUI编程基础知识点总结
2011-01-06 12:54 10641.JOptionPane的使用 JOptionPane 有 ... -
MyEclipse下创建的带包名的类在dos中能编译得到class文件,但不能运行的解决办法
2011-01-03 13:37 2311相信很多朋友遇到过这样一个问题(MyEclipse用久了, ... -
利用java反射机制访问JavaBean中的私有属性
2010-12-29 18:43 1101public class TestReflect ... -
java基础知识整理
2010-12-29 17:29 8441.JVM(虚拟机)的运行过程 代码的装入 代码的校 ... -
java运行机制与执行顺序
2010-12-29 17:20 1131package Test1229;/** * java的 ... -
Andriod开发环境的搭建
2010-12-29 00:14 2689Andriod开发环境的搭建 收藏 几经周转,终于搭建好了 ... -
JDK1.5的新特性
2010-12-29 00:13 884万丈高楼平地起,楼的高度取决于地基的牢固程度,虽然这些东西以前 ... -
Myeclipse删字节码文件报异常的原因
2010-12-28 21:05 943今天帮网友解决了这么个小问题,问题虽小,但还是蛮有收获的,其实 ... -
创建Java代码模板
2010-12-27 22:20 894创建Java代码模版 windows--preferences ...
相关推荐
Java反射机制的实现_Reflection,适合学习了解反射机制。
在本篇文章里小编给大家分享了关于java反射机制Reflection的相关知识点,需要的朋友们学习下。
Java 反射机制、Java 的类反射机制、Java 反射机制的学习、Java 反射Reflection--运行时生成实例 java反射机制的手册文档
Reflection in Java. 介绍Java中的反射机制,候捷谈Java反射机制
轻松掌握java反射技术,虽然讲得比较简单,但是通俗易懂。
Java反射机制及各成份所对应的Reflection APIs
之前上课的时候老师总结的JavaReflection反射学习资料,内容简单易懂,浅显易懂,适合小白入手学习。。
JAVA反射机制及应用例子.。。Reflection API
Java反射机制修改私有成员变量的实现_Reflection,普通方式无法修改私有成员变量的值,但通过反射机制可以实现。
关于java反射机制的很好的讲解,包括Java的反射机制(Reflection)、Class类、如何获得类的相关信息和运用,并且还有相应的练习,有助于更好地学习java反射机制
Java 反射机制主要提供 了以下功能: 在运行时判断任意一个对象所属的类; 在运行时构造任意一个类的对象; 在运行时判断任意一个类所具有的成员变量和方法; 在运行时调用任意一个对象的方法; 生成动态...
反射机制是如今很多流行框架的实现基础,其中包括Spring、Hibernate等。原理性的问题不是本文的重点,接下来让我们在实例中学习这套精彩的机制。 1. 得到某个对象的属性 public Object getProperty(Object owner, ...
java反射,设置属性值,获得属性,具有多个对象同事设置,缓存的处理,
一篇结合了众多关于Java反射机制...Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法)。
1. 反射的用途 Uses of Reflection Reflection is commonly used by programs which require the ...如果能把这句警示时刻放在心里,那么反射机制就会成为一项强大的技术,可以让应用程序做一些几乎不可能做到的事情。
讲述java 反射机制的典型示例,通过学习应该能很好的掌握
Java反射机制与动态代理 浪曦 Java Reflection API 简介 及动态代理
JAVA的内省机制(introspector)与反射机制(reflection).docx
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。...
一、java反射机制概述 Reflection (反射)被视为动态语言的关键,为什么这么说呢,是因为它在运行时就确定下来了。反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的...