当前位置: 代码迷 >> J2SE >> Java反射中构造函数的顺序有关问题
  详细解决方案

Java反射中构造函数的顺序有关问题

热度:9295   发布时间:2013-02-25 00:00:00.0
Java反射中构造函数的顺序问题
有如下代码
Java code
package com.hzt;import java.lang.reflect.Constructor;class Person{         public Person() {             }    public Person(String name){        this.name=name;    }    public Person(int age){        this.age=age;    }    public Person(String name, int age) {        this.age=age;        this.name=name;    }    public String getName() {        return name;    }    public int getAge() {        return age;    }    @Override    public String toString(){        return "["+this.name+"  "+this.age+"]";    }    private String name;    private int age;} class hello{    public static void main(String[] args) {        Class<?> demo=null;        try{            demo=Class.forName("com.hzt.Person");        }catch (Exception e) {            e.printStackTrace();        }        Person per1=null;        Person per2=null;        Person per3=null;        Person per4=null;        //取得全部的构造函数        Constructor<?> cons[]=demo.getConstructors();        try{            per1=(Person)cons[2].newInstance();            per2=(Person)cons[3].newInstance("Rollen");            per3=(Person)cons[1].newInstance(20);            per4=(Person)cons[0].newInstance("Rollen",20);        }catch(Exception e){            e.printStackTrace();        }        System.out.println(per1);        System.out.println(per2);        System.out.println(per3);        System.out.println(per4);    }}

反射调用其构造函数的时候,发现cons[]数组中的顺序无法确定,如果是直接run的话,顺序是 2 3 1 0,但是如果是debug的话,那么顺序就是 3 2 1 0。
使用getConstructors()函数时,返回的构造函数的顺序如何确定?为什么在debug和run的顺序还不同?
谢谢!

------解决方案--------------------------------------------------------
不要这样,用指定的构造方法:

Java code
public static void main(String[] args) {        Class<?> demo = null;        try {            demo = Class.forName("com.hzt.Person");            Constructor cons0 = demo.getConstructor();            Constructor cons1 = demo.getConstructor(String.class);            Constructor cons2 = demo.getConstructor(int.class);            Constructor cons3 = demo.getConstructor(String.class,int.class);                        Person per1 = (Person) cons0.newInstance();            Person per2 = (Person) cons1.newInstance("Rollen");            Person per3 = (Person) cons2.newInstance(20);            Person per4 = (Person) cons3.newInstance("Rollen", 20);                        System.out.println(per1);            System.out.println(per2);            System.out.println(per3);            System.out.println(per4);        }        catch (Exception e) {            e.printStackTrace();        }            }
------解决方案--------------------------------------------------------
探讨

我看了Class 的代码, 第一次取得getConstructors还是掉native函数的。
我猜测还是读.class文件来分析出来的。
所以最可能是的构造函数在.class文件里的顺序。

也许debug和run的class文件不一样? hoho。 随便猜猜。

------解决方案--------------------------------------------------------
C/C++ code
JNIEXPORT jobjectArray JNICALL JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly) {-  NYI();+  ArrayObject* ret = 0;+  JavaObject* tmp = 0;+  JavaObject* Cl = 0;+  llvm_gcroot(Cl, 0);+  llvm_gcroot(ret, 0);+  llvm_gcroot(tmp, 0);++  BEGIN_JNI_EXCEPTION++  Cl = *(JavaObject**)ofClass;++  Jnjvm* vm = JavaThread::get()->getJVM();+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);++  if (cl->isArray() || cl->isInterface() || cl->isPrimitive()) {+    ret = (ArrayObject*)vm->upcalls->constructorArrayClass->doNew(0, vm);+  } else {+    UserClass* realCl = cl->asClass();;+    JnjvmClassLoader* classLoader = cl->classLoader;+    uint32 size = 0;++    for (uint32 i = 0; i < realCl->nbVirtualMethods; ++i) {+      JavaMethod* meth = &realCl->virtualMethods[i];+      bool pub = isPublic(meth->access);+      if (meth->name->equals(classLoader->bootstrapLoader->initName) &&+          (!publicOnly || pub)) {+        ++size;+      }+    }++    ret = (ArrayObject*)vm->upcalls->constructorArrayClass->doNew(size, vm);++    sint32 index = 0;+    for (uint32 i = 0; i < realCl->nbVirtualMethods; ++i) {+      JavaMethod* meth = &realCl->virtualMethods[i];+      bool pub = isPublic(meth->access);+      if (meth->name->equals(classLoader->bootstrapLoader->initName) &&+          (!publicOnly || pub)) {+        UserClass* Cons = vm->upcalls->newConstructor;+        JavaObject * pArr = meth->getParameterTypes(classLoader);+        JavaObject * eArr = meth->getExceptionTypes(classLoader);+        tmp = Cons->doNew(vm);+        vm->upcalls->initConstructor->invokeIntSpecial(vm, Cons, tmp,+          &Cl,          /* declaringClass */+          &pArr,        /* parameterTypes */+          &eArr,        /* checkedExceptions */+          meth->access, /* modifiers */+          i,            /* slot */+          NULL,         /* String signature */+          NULL,         /* annotations */+          NULL          /* parameterAnnotations */+        );+        ArrayObject::setElement(ret, tmp, index);+        index++;+      }+    }+  }++  RETURN_FROM_JNI((jobjectArray)th->pushJNIRef(ret));++  END_JNI_EXCEPTION++  return 0; }
  相关解决方案