创建带参数的对象就比较复杂 ,由于构造函数不止一个,且参数列表参数类型不一要,所以自己要指明构造函数中的参数列表,自己也必须明确参数类型的传入,否则会出现异常的。下面是一些类和方法的说明:
public T newInstance(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
- 如果此方法引发的初始化失败。
好了,下面就是一个实例,包括构造函数中包括自定义的类,基本数据类型,和非基本数据类型。
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.jijing.classDemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Administrator
* 用来演示通过反射来创建对象,带参数的构造方法
*/
public class ClassMain {
public ClassMain(){
}
public static void main(String args[]){
//创建不带参数的对象
//ReflectClass rc1=(ReflectClass) ClassMain.getInstance("com.jijing.classDemo.ReflectClass");
//System.out.println("ReflectClass111="+rc1);
System.out.println("******************************");
ReflectClass rc2=(ReflectClass) ClassMain.getInstance("com.jijing.classDemo.ReflectClass",
new Class[]{Integer.TYPE,String.class,MyClass.class},
new Object[]{20,"我是ReflectClass",new MyClass("我是MyClass")});
System.out.println("ReflectClass222="+rc2);
}
/**
*
* @param className 类路劲的名字
* @return 返回根据className指明的类信息
*/
public static Class getclass(String className){
Class c=null;
try {
c=Class.forName(className);
} catch (ClassNotFoundException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
return c;
}
/**
*
* @param name 类路劲
* @param classParas Class类信息参数列表
* 如果是基本数据类型是可以使用其Tpye类型,如果用class字段是无效的
* 如果是非数据类型可以使用的class字段来创建其Class类信息对象,这些都要遵守。
* @param paras 实际参数列表数据
* @return 返回Object引用的对象,实际实际创建出来的对象,如果要使用可以强制转换为自己想要的对象
*
* 带参数的反射创建对象
*/
public static Object getInstance(String name,Class classParas[],Object paras[]){
Object o=null;
try {
Class c=getclass(name);
Constructor con=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
try {
//信息
o=con.newInstance(paras);//传入当前构造函数要的参数列表
} catch (InstantiationException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (NoSuchMethodException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
return o;//返回这个用Object引用的对象
}
/**
*
* @param name 类路劲
* @return 不带参数的反射创建对象
*/
public static Object getInstance(String name){
Class c=getclass(name);
Object o=null;
try {
o=c.newInstance();
} catch (InstantiationException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
return o;
}
}
/**
*
* @author Administrator
* 自定义一个类型
*/
class MyClass{
private String name="";//名字显示,用来表明创建成功
MyClass(String name){
this.name=name;
show();//显示
}
public void show(){
System.out.println(name);
}
@Override
public String toString(){
return "MyClass="+name;
}
}
/**
*
* @author Administrator
* 通过反射创建对象
*/
class ReflectClass{
private String name="ReflectClass";
public ReflectClass(int age,String name,MyClass my){
this.name=name;
show(age,name,my);
}
// ReflectClass(){//构造函数重载,使用不同的参数列表创建对象
// //没有带参数的构造方法
// }
/**
*
* @param age
* @param name
* @param my
*/
public final void show(int age,String name,MyClass my){
System.out.println("age="+age+" name="+name+" my="+my);
}
@Override
public String toString(){
return "ReflectClass="+name;
}
}
上面有三个方法自己可以拿去用,已经封装好了,就是这三个方法。
/**
*
* @param className 类路劲的名字
* @return 返回根据className指明的类信息
*/
public static Class getclass(String className){
Class c=null;
try {
c=Class.forName(className);
} catch (ClassNotFoundException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
return c;
}
/**
*
* @param name 类路劲
* @param classParas Class类信息参数列表
* 如果是基本数据类型是可以使用其Tpye类型,如果用class字段是无效的
* 如果是非数据类型可以使用的class字段来创建其Class类信息对象,这些都要遵守。
* @param paras 实际参数列表数据
* @return 返回Object引用的对象,实际实际创建出来的对象,如果要使用可以强制转换为自己想要的对象
*
* 带参数的反射创建对象
*/
public static Object getInstance(String name,Class classParas[],Object paras[]){
Object o=null;
try {
Class c=getclass(name);
Constructor con=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
try {
//信息
o=con.newInstance(paras);//传入当前构造函数要的参数列表
} catch (InstantiationException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (NoSuchMethodException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
return o;//返回这个用Object引用的对象
}
/**
*
* @param name 类路劲
* @return 不带参数的反射创建对象
*/
public static Object getInstance(String name){
Class c=getclass(name);
Object o=null;
try {
o=c.newInstance();
} catch (InstantiationException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
return o;
}
像上面的带参数的getInstance反射可以该写一下:
/**
*
* @param name 类路劲
* @param paras 实际参数列表数据
* @return 返回Object引用的对象,实际实际创建出来的对象,如果要使用可以强制转换为自己想要的对象
*
* 带参数的反射创建对象
*/
public static Object getInstance(String name,Object paras[]){
Object o=null;
try {
Class c=getclass(name);
int len=paras.length;
Class classParas[]=new Class[len];
for(int i=0;i<len;++i){
classParas[i]=paras[i].getClass();//返回类信息
System.out.println("classParas[i]="+classParas[i]);
}
Constructor con=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
try {
//信息
o=con.newInstance(paras);//传入当前构造函数要的参数列表
} catch (InstantiationException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (NoSuchMethodException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
}
return o;//返回这个用Object引用的对象
}
但是上面会出现一个问题,如果在编写类时没有注意会出现java.lang.NoSuchMethodException异常,因为基本类型要转换为类的形式才可以通过。
例如这个类:
class ReflectClass{
private String name="ReflectClass";
public ReflectClass(Integer age,String name,MyClass my){
this.name=name;
show(age,name,my);
}
// ReflectClass(){//构造函数重载,使用不同的参数列表创建对象
// //没有带参数的构造方法
// }
/**
*
* @param age
* @param name
* @param my
*/
public final void show(Integer age,String name,MyClass my){
System.out.println("age="+age+" name="+name+" my="+my);
}
@Override
public String toString(){
return "ReflectClass="+name;
}
}
如果要getClass()的话一定要以类的形式存在,请注意这点。