初学者学Java(二十一)-------反射机制

来源:互联网 发布:淘宝兼职客服一般多少 编辑:程序博客网 时间:2024/05/20 18:55

                                           初识反射机制

以前我们访问对象的方法和属性,都是在编译期的时候完成的。但Java可不可以在运行期来实现调用某个类的方法和属性,这个当然是可以的,Java就是通过反射来实现的,反射的英文是Reflection。
        Java 反射机制主要提供了以下功能:
• 在运行时判断任意一个对象所属的类。
• 在运行时构造任意一个类的对象。
• 在运行时判断任意一个类所具有的成员变量和方法。
• 在运行时调用任意一个对象的方法
下面我来说一下Java是如何来完成这个工作了。
我们首先来介绍一个最基本的类Class类。

反射的基础--------Class类

在Java中每个类都有一个且仅有一个Class对象,不管这个类生成多少个新的对象,他都只有一个。这个对象描述了这个类的包括名称在内的一些信息,要想使用反射必须先得到Class对象。下面我们写个程序来测试一下。我们来以String类测试一下:
package reflection;public class TestOne {public static void main(String[] args) {Class classType = String.class;System.out.println(classType);}}
这个测试程序的结果如下:
class java.lang.String
得到Class对象的三种方法
•第一种
因为所有的类都直接或间接的继承自Object类,而Object中有一个方法getClass()方法,这个方法可以得到这个对象所对应的类的Class对象,我们还是以String类为例:
package reflection;public class TestOne {public static void main(String[] args) {String str ="滨州学院csdn高校俱乐部";Class classType = str.getClass();System.out.println(classType);}}
这个测试程序的结果如下:
class java.lang.String
•第二种
Class类本身有个静态方法:
public static Class<?> forName(String className)
这个方法可以返回与带有给定字符串名的类或接口相关联的 Class 对象。测试一下:
package reflection;public class TestOne {public static void main(String[] args) throws Exception {Class classType = Class.forName("java.lang.String");System.out.println(classType);}}
这个测试程序的结果如下:

class java.lang.String
•第三种
使用类的.class 语法,也可以得到Class对象,就像我第一个例子一样,我就不再演示了。
Class还有以下几个方法:
– getName():获得类的完整名字。
– getFields():获得类的public类型的属性。
– getDeclaredFields():获得类的所有属性。
– getMethods():获得类的public类型的方法。
– getDeclaredMethods():获得类的所有方法。

getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
下面来讲一下通过默认构造方法创建一个新对象:
例:
package reflection;public class TestOne {public static void main(String[] args) throws Exception {Class classType = Class.forName("java.lang.String");String str =(String) classType.newInstance();}}
因为newInstance()方法的返回值是Object类型,所以需要强制转换,或者使用泛型:
package reflection;public class TestOne {public static void main(String[] args) throws Exception {Class<String> classType = String.class;String str =classType.newInstance();}}

调用构造方法,普通方法,属性的类-------Constructor 类,Method类,Field 类

刚刚我们演示了通过默认构造方法创建一个新对象,但如果想要通过一个类的有参数的构造方法来创建一个对象,就必须通过

Constructor 类。用这个类来调用有参构造的方式如下例:

package reflection;import java.lang.reflect.*;class A{public A(int a){}}public class TestOne {public static void main(String[] args) throws Exception {Class<A> classType = A.class;Constructor<A>  con = classType.getConstructor(new Class[]{int.class});A a = con.newInstance(new Object[]{1});}}
Class类的

getConstructor();方法是用来获取构造方法类的对象,参数是构造方法的参数类型,因为同一个类不同的构造方法只有参数不同,所以这样就可以获取类的构造方法,如果没有参数就是调用无参构造函数。

创建了对象后我们就要调用他的方法和属性,分别用到了

Method类,Field 类。

调用方法:
package reflection;import java.lang.reflect.*;class A{public int a;public A(int a){this.a = a;}public void b(){a  = 2;}}public class TestOne {public static void main(String[] args) throws Exception {Class<A> classType = A.class;Constructor<A>  con = classType.getConstructor(new Class[]{int.class});A a = con.newInstance(new Object[]{1});Method met = classType.getMethod("b", new Class[]{});met.invoke(a, new Object[]{});}}

调用属性
package reflection;import java.lang.reflect.*;class A{public int a;public A(int a){this.a = a;}public void b(){a  = 2;}}public class TestOne {public static void main(String[] args) throws Exception {Class<A> classType = A.class;Constructor<A>  con = classType.getConstructor(new Class[]{int.class});A a = con.newInstance(new Object[]{1});Field fie = classType.getField("a");fie.set(a, 3);System.out.println(a.a);}}

结果为3.
如果想要调用私有方法,就要像下面这个例子一样:
package reflection;import java.lang.reflect.*;class A{private int a;public int getA() {return a;}public void setA(int a) {this.a = a;}public A(int a){this.a = a;}public void b(){a  = 2;}}public class TestOne {public static void main(String[] args) throws Exception {Class<A> classType = A.class;Constructor<A>  con = classType.getConstructor(new Class[]{int.class});A a = con.newInstance(new Object[]{1});Field fie = classType.getDeclaredField("a");fie.setAccessible(true);fie.set(a, 3);System.out.println(a.getA());}}

调用私有方法,和这个是同理的。就不再举例子了。
以上就是反射的一些基本内容。



原创粉丝点击