有如下代码
- 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(); } }
------解决方案--------------------------------------------------------
------解决方案--------------------------------------------------------
- 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; }