首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

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

2012-11-08 
Java反射中构造函数的顺序问题有如下代码Java codepackage com.hztimport java.lang.reflect.Constructor

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; } 


[解决办法]
无需关心顺序
如果是指定了参数类型列表,那么你必然知道如何传入参数
如果是直接获取构造数组,那么你在遍历的时候,可以通过getParameterTypes来获得参数类型列表
然后就可以继续做了

送LZ一句话:不要去关心不需要你关心的东西~
[解决办法]
public Constructor<?>[] getDeclaredConstructors()
throws SecurityException
Returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object. These are public, protected, default (package) access, and private constructors. The elements in the array returned are not sorted and are not in any particular order. If the class has a default constructor, it is included in the returned array. This method returns an array of length 0 if this Class object represents an interface, a primitive type, an array class, or void. 
See The Java Language Specification, section 8.2. 


getConstructors() 和 getDeclaredConstructors 应该是彼此间重用了的。
api说明了返回无特定顺序,代码也没有直接表明是按某特定顺序。


[解决办法]
返回的构造器数组是不依赖于声明顺序的,这是jdk本身决定的,他就没有保证顺序
[解决办法]

探讨

引用:

public Constructor<?>[] getDeclaredConstructors()
throws SecurityException
Returns an array of Constructor objects reflecting all the constructors declared ……

既然说明里说了没有任何顺序,看来是真……

热点排行
Bad Request.