Java通过反射创建对象
2015-09-28 13:55
495 查看
java可以在运行时动态获取某个类的类信息,这就是java的反射。
一、通过反射创建不带参数的对象
这个比较简单,不需要获取这个类的构造方法类,不需要指明构造参数的参数列表。下面是要使用的类和方法,使用步骤如下:
Class(类):
以下示例使用
返回与带有给定字符串名的类或接口相关联的
其中
例如,以下代码片段返回命名为
调用forName("X")将导致命名为X的类被初始化。
参数:
如果链接失败
如果此方法所激发的初始化失败
如果无法定位该类
创建此Class对象所表示的类的一个新实例。如同用一个带有一个空参数列表的
注意,此方法传播null构造方法所抛出的任何异常,包括已检查的异常。使用此方法可以有效地绕过编译时的异常检查,而在其他情况下编译器都会执行该检查。
返回:此对象所表示的类的一个新分配的实例。抛出:
构造方法是不可访问的。
void;或者该类没有null构造方法;或者由于其他某种原因导致实例化失败。
调用
调用者的类加载器不同于也不是当前类的类加载器的一个祖先,并且对
这个方法是Class类中的方法,且只能创建不带任何参数的对象形式(构造函数没有参数列表)。直接返回T模版类型的对象,自己要把它转换为实际类型。
下面是实际例子:
Classc=Class.forName("java.lang.String");
Strings=(String)c.newInstance();
二、创建带参数的对象
创建带参数的对象就比较复杂,由于构造函数不止一个,且参数列表参数类型不一要,所以自己要指明构造函数中的参数列表,自己也必须明确参数类型的传入,否则会出现异常的。下面是一些类和方法的说明:
返回一个
Class对象按声明顺序标识构造方法的形参类型。如果此
要反映的构造方法是此
参数:
如果找不到匹配的方法。
如果存在安全管理器s,并满足下列任一条件:
调用
调用者的类加载器不同于也不是当前类的类加载器的一个祖先,并且对
从以下版本开始:JDK1.1
里面要注意的就是parametrrTypes这个Class类型的参数列表,用来指明当前你要创建的类的某个构造方法的参数列表,且顺序要是当前这个类的构造方法中声明的参数列表相同。注意都是Class类型,指明一些类信息就可以了。可以按照下面的规则来传入相应的类信息参数列表:例如:Integer类,它有两个构造函数,
构造一个新分配的
参数:
这个构造函数指明的Class参数列表是一个IntergerClass类型的类对象这么写:Interger.TYPE:返回的是其Class类信息
另一个构造函数:
构造一个新分配的
10的值)相同的方式将该字符串转换成
参数:
如果
其参数类型是这样创建:String.class
class参数列表创建总结:如果是基本类型请使用它们的Type字段,如果是非基本类型使用class字段来返回其CLass类信息。
现在就是如何创建对象了,对于带参数的对象,你要传入参数,可以使用newInstance(参数列表)来创建对象,这个Constructor对象的方法。
使用此
如果底层构造方法所需形参数为0,则所提供的
如果构造方法的声明类是非静态上下文的内部类,则构造方法的第一个参数需要是封闭实例;请参阅Java语言规范第15.9.3节。
如果所需的访问检查和参数检查获得成功并且实例化继续进行,这时构造方法的声明类尚未初始化,则初始化这个类。
如果构造方法正常完成,则返回新创建且已初始化的实例。
参数:
Java语言访问控制并且底层构造方法是不可访问的。
如果底层构造方法抛出异常。
好了,下面就是一个实例,包括构造函数中包括自定义的类,基本数据类型,和非基本数据类型。
[java]view
plaincopy
/*
*Tochangethistemplate,chooseTools|Templates
*andopenthetemplateintheeditor.
*/
packagecom.jijing.classDemo;
importjava.lang.reflect.Constructor;
importjava.lang.reflect.InvocationTargetException;
importjava.util.logging.Level;
importjava.util.logging.Logger;
/**
*
*@authorAdministrator
*用来演示通过反射来创建对象,带参数的构造方法
*/
publicclassClassMain{
publicClassMain(){
}
publicstaticvoidmain(Stringargs[]){
//创建不带参数的对象
//ReflectClassrc1=(ReflectClass)ClassMain.getInstance("com.jijing.classDemo.ReflectClass");
//System.out.println("ReflectClass111="+rc1);
System.out.println("******************************");
ReflectClassrc2=(ReflectClass)ClassMain.getInstance("com.jijing.classDemo.ReflectClass",
newClass[]{Integer.TYPE,String.class,MyClass.class},
newObject[]{20,"我是ReflectClass",newMyClass("我是MyClass")});
System.out.println("ReflectClass222="+rc2);
}
/**
*
*@paramclassName类路劲的名字
*@return返回根据className指明的类信息
*/
publicstaticClassgetclass(StringclassName){
Classc=null;
try{
c=Class.forName(className);
}catch(ClassNotFoundExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returnc;
}
/**
*
*@paramname类路劲
*@paramclassParasClass类信息参数列表
*如果是基本数据类型是可以使用其Tpye类型,如果用class字段是无效的
*如果是非数据类型可以使用的class字段来创建其Class类信息对象,这些都要遵守。
*@paramparas实际参数列表数据
*@return返回Object引用的对象,实际实际创建出来的对象,如果要使用可以强制转换为自己想要的对象
*
*带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname,ClassclassParas[],Objectparas[]){
Objecto=null;
try{
Classc=getclass(name);
Constructorcon=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
try{
//信息
o=con.newInstance(paras);//传入当前构造函数要的参数列表
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalArgumentExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(InvocationTargetExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
}catch(NoSuchMethodExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(SecurityExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;//返回这个用Object引用的对象
}
/**
*
*@paramname类路劲
*@return不带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname){
Classc=getclass(name);
Objecto=null;
try{
o=c.newInstance();
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;
}
}
/**
*
*@authorAdministrator
*自定义一个类型
*/
classMyClass{
privateStringname="";//名字显示,用来表明创建成功
MyClass(Stringname){
this.name=name;
show();//显示
}
publicvoidshow(){
System.out.println(name);
}
@Override
publicStringtoString(){
return"MyClass="+name;
}
}
/**
*
*@authorAdministrator
*通过反射创建对象
*/
classReflectClass{
privateStringname="ReflectClass";
publicReflectClass(intage,Stringname,MyClassmy){
this.name=name;
show(age,name,my);
}
//ReflectClass(){//构造函数重载,使用不同的参数列表创建对象
////没有带参数的构造方法
//}
/**
*
*@paramage
*@paramname
*@parammy
*/
publicfinalvoidshow(intage,Stringname,MyClassmy){
System.out.println("age="+age+"name="+name+"my="+my);
}
@Override
publicStringtoString(){
return"ReflectClass="+name;
}
}
上面有三个方法自己可以拿去用,已经封装好了,就是这三个方法。
/**
*
*@paramclassName类路劲的名字
*@return返回根据className指明的类信息
*/
publicstaticClassgetclass(StringclassName){
Classc=null;
try{
c=Class.forName(className);
}catch(ClassNotFoundExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returnc;
}
/**
*
*@paramname类路劲
*@paramclassParasClass类信息参数列表
*如果是基本数据类型是可以使用其Tpye类型,如果用class字段是无效的
*如果是非数据类型可以使用的class字段来创建其Class类信息对象,这些都要遵守。
*@paramparas实际参数列表数据
*@return返回Object引用的对象,实际实际创建出来的对象,如果要使用可以强制转换为自己想要的对象
*
*带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname,ClassclassParas[],Objectparas[]){
Objecto=null;
try{
Classc=getclass(name);
Constructorcon=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
try{
//信息
o=con.newInstance(paras);//传入当前构造函数要的参数列表
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalArgumentExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(InvocationTargetExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
}catch(NoSuchMethodExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(SecurityExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;//返回这个用Object引用的对象
}
/**
*
*@paramname类路劲
*@return不带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname){
Classc=getclass(name);
Objecto=null;
try{
o=c.newInstance();
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;
}
像上面的带参数的getInstance反射可以该写一下:
/**
*
*@paramname类路劲
*@paramparas实际参数列表数据
*@return返回Object引用的对象,实际实际创建出来的对象,如果要使用可以强制转换为自己想要的对象
*
*带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname,Objectparas[]){
Objecto=null;
try{
Classc=getclass(name);
intlen=paras.length;
ClassclassParas[]=newClass[len];
for(inti=0;i<len;++i){
classParas[i]=paras[i].getClass();//返回类信息
System.out.println("classParas[i]="+classParas[i]);
}
Constructorcon=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
try{
//信息
o=con.newInstance(paras);//传入当前构造函数要的参数列表
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalArgumentExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(InvocationTargetExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
}catch(NoSuchMethodExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(SecurityExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;//返回这个用Object引用的对象
}
但是上面会出现一个问题,如果在编写类时没有注意会出现java.lang.NoSuchMethodException异常,因为基本类型要转换为类的形式才可以通过。例如这个类:
[java]view
plaincopy
classReflectClass{
privateStringname="ReflectClass";
publicReflectClass(Integerage,Stringname,MyClassmy){
this.name=name;
show(age,name,my);
}
//ReflectClass(){//构造函数重载,使用不同的参数列表创建对象
////没有带参数的构造方法
//}
/**
*
*@paramage
*@paramname
*@parammy
*/
publicfinalvoidshow(Integerage,Stringname,MyClassmy){
System.out.println("age="+age+"name="+name+"my="+my);
}
@Override
publicStringtoString(){
return"ReflectClass="+name;
}
}
如果要getClass()的话一定要以类的形式存在,请注意这点。
一、通过反射创建不带参数的对象
这个比较简单,不需要获取这个类的构造方法类,不需要指明构造参数的参数列表。下面是要使用的类和方法,使用步骤如下:
Class(类):
Class类的实例表示正在运行的Java应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为Class对象的一个类,所有具有相同元素类型和维数的数组都共享该
Class对象。基本的Java类型(
boolean、
byte、
char、
short、
int、
long、
float和
double)和关键字
void也表示为
Class对象。
Class没有公共构造方法。
Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的
defineClass方法自动构造的。
以下示例使用
Class对象来显示对象的类名:
voidprintClassName(Objectobj){System.out.println("Theclassof"+obj+"is"+obj.getClass().getName());}
这个类就是类对象,是具体某个类对象,通常我们说说的对象是,某个类的对象,而Class是类级别的对象,描述的类的信息。
例如Stringa=newString();
这个a指的是类String的对象,那么什么是类对象呢,看这个例子:
Classc=String.class;这个c就是String的类对象,描述的是String的信息。不是对象信息。
ClassforName(StringclassName):
返回与带有给定字符串名的类或接口相关联的
Class对象。调用此方法等效于:
Class.forName(className,true,currentLoader)
其中
currentLoader表示当前类的定义类加载器。
例如,以下代码片段返回命名为
java.lang.Thread的类的运行时
Class描述符。
Classt=Class.forName("java.lang.Thread")
调用forName("X")将导致命名为X的类被初始化。
参数:
className-所需类的完全限定名。返回:具有指定名的类的
Class对象。抛出:
-LinkageError
如果链接失败
-ExceptionInInitializerError
如果此方法所激发的初始化失败
-ClassNotFoundException
如果无法定位该类
通过指明类所在的具体位置来生成这个类的类对象。注意:className指明的是具体的这个类所在的位置,例如java内置的String类,那么它的位置是className=java.lang.String;如果自己创建的类,当加载到项目中后请也指明其具体的位置,例如有一个自己创建的类GameCanvas在com.jijing.gameDemo中,className=com.jijing.gameDemo.GameCanvas;
publicTnewInstance();
创建此Class对象所表示的类的一个新实例。如同用一个带有一个空参数列表的
new表达式实例化该类。如果该类尚未初始化,则初始化这个类。
注意,此方法传播null构造方法所抛出的任何异常,包括已检查的异常。使用此方法可以有效地绕过编译时的异常检查,而在其他情况下编译器都会执行该检查。
Constructor.newInstance方法将该构造方法所抛出的任何异常包装在一个(已检查的)
InvocationTargetException中,从而避免了这一问题。
返回:此对象所表示的类的一个新分配的实例。抛出:
IllegalAccessException-如果该类或其null
构造方法是不可访问的。
-如果此InstantiationException
Class表示一个抽象类、接口、数组类、基本类型或
void;或者该类没有null构造方法;或者由于其他某种原因导致实例化失败。
-如果该方法引发的初始化失败。ExceptionInInitializerError
-如果存在安全管理器s,并满足下列任一条件:SecurityException
调用
s.checkMemberAccess(this,Member.PUBLIC)拒绝创建该类的新实例
调用者的类加载器不同于也不是当前类的类加载器的一个祖先,并且对
s.checkPackageAccess()的调用拒绝访问该类的包
这个方法是Class类中的方法,且只能创建不带任何参数的对象形式(构造函数没有参数列表)。直接返回T模版类型的对象,自己要把它转换为实际类型。
下面是实际例子:
Classc=Class.forName("java.lang.String");
Strings=(String)c.newInstance();
二、创建带参数的对象
创建带参数的对象就比较复杂,由于构造函数不止一个,且参数列表参数类型不一要,所以自己要指明构造函数中的参数列表,自己也必须明确参数类型的传入,否则会出现异常的。下面是一些类和方法的说明:
publicConstructor< T>getConstructor( Class<?>...parameterTypes)throws NoSuchMethodException, SecurityException
返回一个
Constructor对象,它反映此
Class对象所表示的类的指定公共构造方法。
parameterTypes参数是
Class对象的一个数组,这些
Class对象按声明顺序标识构造方法的形参类型。如果此
Class对象表示非静态上下文中声明的内部类,则形参类型作为第一个参数包括显示封闭的实例。
要反映的构造方法是此
Class对象所表示的类的公共构造方法,其形参类型与
parameterTypes所指定的参数类型相匹配。
参数:
parameterTypes-参数数组返回:与指定的
parameterTypes相匹配的公共构造方法的
Constructor对象抛出:
-NoSuchMethodException
如果找不到匹配的方法。
-SecurityException
如果存在安全管理器s,并满足下列任一条件:
调用
s.checkMemberAccess(this,Member.PUBLIC)拒绝访问构造方法
调用者的类加载器不同于也不是当前类的类加载器的一个祖先,并且对
s.checkPackageAccess()的调用拒绝访问该类的包
从以下版本开始:JDK1.1
里面要注意的就是parametrrTypes这个Class类型的参数列表,用来指明当前你要创建的类的某个构造方法的参数列表,且顺序要是当前这个类的构造方法中声明的参数列表相同。注意都是Class类型,指明一些类信息就可以了。可以按照下面的规则来传入相应的类信息参数列表:例如:Integer类,它有两个构造函数,
publicInteger(intvalue)
构造一个新分配的
Integer对象,它表示指定的
int值。
参数:
value-
Integer对象表示的值。
这个构造函数指明的Class参数列表是一个IntergerClass类型的类对象这么写:Interger.TYPE:返回的是其Class类信息
另一个构造函数:
publicInteger(Strings)throws NumberFormatException
构造一个新分配的
Integer对象,它表示
String参数所指示的
int值。使用与
parseInt方法(对基数为
10的值)相同的方式将该字符串转换成
int值。
参数:
s-要转换为
Integer的
String。抛出:
-NumberFormatException
如果
String不包含可解析的整数。另请参见:
parseInt(java.lang.String,int)
其参数类型是这样创建:String.class
class参数列表创建总结:如果是基本类型请使用它们的Type字段,如果是非基本类型使用class字段来返回其CLass类信息。
现在就是如何创建对象了,对于带参数的对象,你要传入参数,可以使用newInstance(参数列表)来创建对象,这个Constructor对象的方法。
publicTnewInstance( Object...initargs)throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
使用此
Constructor对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。个别参数会自动解包,以匹配基本形参,必要时,基本参数和引用参数都要进行方法调用转换。
如果底层构造方法所需形参数为0,则所提供的
initargs数组的长度可能为0或null。
如果构造方法的声明类是非静态上下文的内部类,则构造方法的第一个参数需要是封闭实例;请参阅Java语言规范第15.9.3节。
如果所需的访问检查和参数检查获得成功并且实例化继续进行,这时构造方法的声明类尚未初始化,则初始化这个类。
如果构造方法正常完成,则返回新创建且已初始化的实例。
参数:
initargs-将作为变量传递给构造方法调用的对象数组;基本类型的值被包装在适当类型的包装器对象(如
Float中的float)中。返回:通过调用此对象表示的构造方法来创建的新对象抛出:
-如果此IllegalAccessException
Constructor对象实施
Java语言访问控制并且底层构造方法是不可访问的。
-如果实参和形参的数量不同;如果基本参数的解包转换失败;如果在可能的解包后,无法通过方法调用转换将参数值转换为相应的形参类型;如果此构造方法属于枚举类型。IllegalArgumentException
-如果声明底层构造方法的类表示抽象类。InstantiationException
-InvocationTargetException
如果底层构造方法抛出异常。
-如果此方法引发的初始化失败。ExceptionInInitializerError
好了,下面就是一个实例,包括构造函数中包括自定义的类,基本数据类型,和非基本数据类型。
[java]view
plain
/*
*Tochangethistemplate,chooseTools|Templates
*andopenthetemplateintheeditor.
*/
packagecom.jijing.classDemo;
importjava.lang.reflect.Constructor;
importjava.lang.reflect.InvocationTargetException;
importjava.util.logging.Level;
importjava.util.logging.Logger;
/**
*
*@authorAdministrator
*用来演示通过反射来创建对象,带参数的构造方法
*/
publicclassClassMain{
publicClassMain(){
}
publicstaticvoidmain(Stringargs[]){
//创建不带参数的对象
//ReflectClassrc1=(ReflectClass)ClassMain.getInstance("com.jijing.classDemo.ReflectClass");
//System.out.println("ReflectClass111="+rc1);
System.out.println("******************************");
ReflectClassrc2=(ReflectClass)ClassMain.getInstance("com.jijing.classDemo.ReflectClass",
newClass[]{Integer.TYPE,String.class,MyClass.class},
newObject[]{20,"我是ReflectClass",newMyClass("我是MyClass")});
System.out.println("ReflectClass222="+rc2);
}
/**
*
*@paramclassName类路劲的名字
*@return返回根据className指明的类信息
*/
publicstaticClassgetclass(StringclassName){
Classc=null;
try{
c=Class.forName(className);
}catch(ClassNotFoundExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returnc;
}
/**
*
*@paramname类路劲
*@paramclassParasClass类信息参数列表
*如果是基本数据类型是可以使用其Tpye类型,如果用class字段是无效的
*如果是非数据类型可以使用的class字段来创建其Class类信息对象,这些都要遵守。
*@paramparas实际参数列表数据
*@return返回Object引用的对象,实际实际创建出来的对象,如果要使用可以强制转换为自己想要的对象
*
*带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname,ClassclassParas[],Objectparas[]){
Objecto=null;
try{
Classc=getclass(name);
Constructorcon=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
try{
//信息
o=con.newInstance(paras);//传入当前构造函数要的参数列表
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalArgumentExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(InvocationTargetExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
}catch(NoSuchMethodExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(SecurityExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;//返回这个用Object引用的对象
}
/**
*
*@paramname类路劲
*@return不带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname){
Classc=getclass(name);
Objecto=null;
try{
o=c.newInstance();
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;
}
}
/**
*
*@authorAdministrator
*自定义一个类型
*/
classMyClass{
privateStringname="";//名字显示,用来表明创建成功
MyClass(Stringname){
this.name=name;
show();//显示
}
publicvoidshow(){
System.out.println(name);
}
@Override
publicStringtoString(){
return"MyClass="+name;
}
}
/**
*
*@authorAdministrator
*通过反射创建对象
*/
classReflectClass{
privateStringname="ReflectClass";
publicReflectClass(intage,Stringname,MyClassmy){
this.name=name;
show(age,name,my);
}
//ReflectClass(){//构造函数重载,使用不同的参数列表创建对象
////没有带参数的构造方法
//}
/**
*
*@paramage
*@paramname
*@parammy
*/
publicfinalvoidshow(intage,Stringname,MyClassmy){
System.out.println("age="+age+"name="+name+"my="+my);
}
@Override
publicStringtoString(){
return"ReflectClass="+name;
}
}
上面有三个方法自己可以拿去用,已经封装好了,就是这三个方法。
/**
*
*@paramclassName类路劲的名字
*@return返回根据className指明的类信息
*/
publicstaticClassgetclass(StringclassName){
Classc=null;
try{
c=Class.forName(className);
}catch(ClassNotFoundExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returnc;
}
/**
*
*@paramname类路劲
*@paramclassParasClass类信息参数列表
*如果是基本数据类型是可以使用其Tpye类型,如果用class字段是无效的
*如果是非数据类型可以使用的class字段来创建其Class类信息对象,这些都要遵守。
*@paramparas实际参数列表数据
*@return返回Object引用的对象,实际实际创建出来的对象,如果要使用可以强制转换为自己想要的对象
*
*带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname,ClassclassParas[],Objectparas[]){
Objecto=null;
try{
Classc=getclass(name);
Constructorcon=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
try{
//信息
o=con.newInstance(paras);//传入当前构造函数要的参数列表
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalArgumentExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(InvocationTargetExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
}catch(NoSuchMethodExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(SecurityExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;//返回这个用Object引用的对象
}
/**
*
*@paramname类路劲
*@return不带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname){
Classc=getclass(name);
Objecto=null;
try{
o=c.newInstance();
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;
}
像上面的带参数的getInstance反射可以该写一下:
/**
*
*@paramname类路劲
*@paramparas实际参数列表数据
*@return返回Object引用的对象,实际实际创建出来的对象,如果要使用可以强制转换为自己想要的对象
*
*带参数的反射创建对象
*/
publicstaticObjectgetInstance(Stringname,Objectparas[]){
Objecto=null;
try{
Classc=getclass(name);
intlen=paras.length;
ClassclassParas[]=newClass[len];
for(inti=0;i<len;++i){
classParas[i]=paras[i].getClass();//返回类信息
System.out.println("classParas[i]="+classParas[i]);
}
Constructorcon=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
try{
//信息
o=con.newInstance(paras);//传入当前构造函数要的参数列表
}catch(InstantiationExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalAccessExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(IllegalArgumentExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(InvocationTargetExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
}catch(NoSuchMethodExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}catch(SecurityExceptionex){
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE,null,ex);
}
returno;//返回这个用Object引用的对象
}
但是上面会出现一个问题,如果在编写类时没有注意会出现java.lang.NoSuchMethodException异常,因为基本类型要转换为类的形式才可以通过。例如这个类:
[java]view
plain
classReflectClass{
privateStringname="ReflectClass";
publicReflectClass(Integerage,Stringname,MyClassmy){
this.name=name;
show(age,name,my);
}
//ReflectClass(){//构造函数重载,使用不同的参数列表创建对象
////没有带参数的构造方法
//}
/**
*
*@paramage
*@paramname
*@parammy
*/
publicfinalvoidshow(Integerage,Stringname,MyClassmy){
System.out.println("age="+age+"name="+name+"my="+my);
}
@Override
publicStringtoString(){
return"ReflectClass="+name;
}
}
如果要getClass()的话一定要以类的形式存在,请注意这点。
相关文章推荐
- 解决Eclipse编译Debug certificate expired的问题
- Java NIO 缓冲技术详解
- kafka+storm java代码
- JAVA算法_快速排序
- Eclipse 4.4(luna) 安装fatjar插件时报错的问题
- Eclipse将引用了第三方jar包的Java项目打包成jar文件的两种方法
- springmvc如何访问静态文件,例如jpg,js,css
- Java基础知识总结(续)
- 用NetBeans做教学选课系统的登录界面
- 清除Eclipse中SVN用户的方法
- struts2标签-下拉列表的两种写法
- Java基础知识总结
- 清除Eclipse中SVN用户的方法
- Java习题
- win7系统eclipse下切换SVN用户
- Java基础知识强化之IO流笔记01:异常的概述和分类
- java环境变量配置,卸载
- Spring学习笔记 在XML配置文件中使用properties文件的键值
- SpringMVC中的自定义视图使用BeanNameViewResolver出现了不能使用的错误解决
- 多方法比较