java method 创建_Java的反射机制,创建新类的捷径,大师们的杰作!

前两天在编东西的时候遇到了这样一个问题,我在JFrame上放了一个JSplitPane,左右分开的,我想在左边放一个JTree,右边则放一个JPanel。我想达到这样一个效果,首先定义一些个JPanel,当点击树时我要得到被点击的结点的名称,然后根据这个名称去实例化与它名称相同的面板放在JSplitPane的右边。这样,在监听器里只写一个实例化面板的代码就行了,可是我得到的是一个String,这可犯难了,不可能用new关键字去直接实例化。经过在CSDN上的讨教,我终于还是用到了Java的反射。

其实这里需要用到Java里非常重要的一个概念——RTTI(Run-Time

Type

Identification,即运行时类型信息)。Java在运行时识别对象和类型的信息主要有两种方式:一种是“传统的”RTTI,它假定我们在编译时已经知道了所有的类型;另一种是“反射”机制,他允许我们在运行时发现和使用类的信息,RTTI的含义就是在运行时识别一个对象的类型。

首先是Class对象,它用来创建类的所有的“常规”的对象。Bruce

Eckel的《Thinking In

Java》中介绍说:“每当编写并且编译了一个新类,就会产生一个Class对象(更恰当地说,是被保存在一个同名的.class文件中)。为了生成这个类的对象,运行这个程序的Java虚拟机(JVM)将使用被称为‘类加载器’的字系统。”类加载器字系统实际上可以包含一条类加载器链,但是只有一个原生类加载器,它是JVM实现的一部分。所有的类都是在对其第一次使用时,动态加载到JVM中的。Java程序在它开始运行之前并非被完全加载,其各个部分是在必需时才加载的。列加载器首先检查这个类的Class对象是否已经加载。如果尚未加载,默认的类加载器就会根据类名查找.class文件。一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有对象。

我们比较感兴趣的是这样一个方法:

Class.forName(String str)

这个方法是Class类的一个static成员。forName()是取得Class对象的引用的一种方法,它返回的是一个表示该对象的实际类型的Class引用,也就是一个这个引用的Class类型的对象。

Class的newInstance()方法是实现“虚拟构造器”的一种途径,Bruce说:“虚拟构造器允许你声明:我不知道你的确切类型,但是无论如何要正确的创建你自己。”如果使用newInstance()来创建的类必须带有默认的构造器。那么,如果构造器带参,我们又该怎么办呢?

不要怀疑大师们的努力,问题总是要解决的。

如果所要创建的类有无参构造器,那么我们可以直接应用:

Object obj =

Class.forName(包名+类名).newInstance();

注意,这个返回的是一个Class类型的对象,我们用Object类型的对象来接收,之后把它强制转换成要实例化的对象就可以了。

如果所要创建的类含有带参的构造器,那么我们应该这样来做:假设参数是两个String型的,那么

Class[] params = new

Class[]{String.class,String.class};

Object[]

newparams = new Object[]{"test","test"};

Class.forName(包名+类名).getConstructor(params).newInstance(Newparams);

这样我们就可以创建要使用的类了,用一个Object类型的对象来接收,之后再强制转换成要使用的类,就可以了。Class.forName()生成的结果在编译时是不可知的,反射机制的价值是很惊人的,但Bruce却说了,反射机制并没有什么神奇之处。当通过反射与一个未知类型的对象打交道时,JVM只是简单地检查这个对象,看它属于哪个特定的类(就像RTTI那样)。RTTI与反射之间真正的区别只在于,对RTTI来说,编译器在编译时打开和检查.class文件;而对于反射机制来说,.class文件在编译时是不可获得的,所有是在运行时打开和检查.class。

一下是一些在网上的摘录,一些很不错的东东!!

检测类

1.Retrieving Class Objects

获取一个Class对象(metadata)

a,从对象的实例获取。

Class c = mystery.getClass();//(return Class)

b,从子类的实例获取

TextField t = new TextField();

Class c = t.getClass();

Class s = c.getSuperclass();

c,知道类名,则可以把.class加入到名字之后来获取。

Class c = java.awt.Button.class;

d,如果类名在编译时是未知的,则可以使用Class.forName()方法来获取.

Class c = Class.forName(classString);

2.Getting the Class Name

获取类名称

c.getName();

例如:

import java.lang.reflect.*;

import java.awt.*;

class SampleName {

public

static void main(String[] args) {

Button b = new Button();

printName(b);

}

static void

printName(Object o) {

Class c = o.getClass();

String s = c.getName();

System.out.println(s);

}

}

3.Discovering Class Modifiers

检索修改符

a.通过getModifiers()方法获取一个整型标识值。

b.通过java.reflect.Modifier对象的isPublic, isAbstract, 和

isFinal方法判断此值.

例如:

import java.lang.reflect.*;

import java.awt.*;

class SampleModifier {

public

static void main(String[] args) {

String s = new String();

printModifiers(s);

}

public

static void printModifiers(Object o) {

Class c = o.getClass();

int m = c.getModifiers();

if (Modifier.isPublic(m))

System.out.println("public");

if (Modifier.isAbstract(m))

System.out.println("abstract");

if (Modifier.isFinal(m))

System.out.println("final");

}

}

4.Finding Superclasses

检索父类

例如:

import java.lang.reflect.*;

import java.awt.*;

class SampleSuper {

public

static void main(String[] args) {

Button b = new Button();

printSuperclasses(b);

}

static void

printSuperclasses(Object o) {

Class subclass = o.getClass();

Class superclass = subclass.getSuperclass();

while (superclass != null) {

String className = superclass.getName();

System.out.println(className);

subclass = superclass;

superclass = subclass.getSuperclass();

}

}

}

5.Identifying the Interfaces

Implemented by a Class

检索指定类实现的接口

例如:

import java.lang.reflect.*;

import java.io.*;

class SampleInterface {

public

static void main(String[] args) {

try {

RandomAccessFile r = new RandomAccessFile("myfile", "r");

printInterfaceNames(r);

} catch (IOException e) {

System.out.println(e);

}

}

static void

printInterfaceNames(Object o) {

Class c = o.getClass();

Class[] theInterfaces = c.getInterfaces();

for (int i = 0; i < theInterfaces.length; i++)

{

String interfaceName = theInterfaces[i].getName();

System.out.println(interfaceName);

}

}

}

6.Examining Interfaces

判定一个类是不是接口

import java.lang.reflect.*;

import java.util.*;

class SampleCheckInterface {

public

static void main(String[] args) {

Class thread = Thread.class;

Class runnable = Runnable.class;

verifyInterface(thread);

verifyInterface(runnable);

}

static void

verifyInterface(Class c) {

String name = c.getName();

if (c.isInterface()) {

System.out.println(name + " is an interface.");

} else {

System.out.println(name + " is a class.");

}

}

}

如:c.isInterface()

7.Identifying Class Fields

找出指定类所有的域成员

每个数据成员可以用java.reflect.Field来封闭其名称,类型,修改符的集合。

也可以通过相应的方法获取或设置到该成员的值。

如:

import java.lang.reflect.*;

import java.awt.*;

class SampleField {

public

static void main(String[] args) {

GridBagConstraints g = new GridBagConstraints();

printFieldNames(g);

}

static void

printFieldNames(Object o) {

Class c = o.getClass();

Field[] publicFields = c.getFields();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值