我不能创建嵌套类的实例,也不能初始化字段。我想通过单元测试

时间:2015-11-06 12:52:56

标签: java reflection junit

我在调试模式下获得嵌套类的类类型,但我可以'创建一个实例,在下一步中初始化嵌套实例的Fields。 (见我的注释行)。所以我的单元测试因错误而失败。

<?php
    $server_name = "127.0.0.1";
    $server_username = "root";
    $server_password = "";
    $db_name=$_SESSION["db_name"];

    //echo "<br>"."Attempting connection to database " . $db_name . "<br>";
    try {
        $connect = new PDO("mysql:host=$server_name;dbname=$db_name", $server_username, $server_password);

        $connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        //echo "<br>"."Connected successfully to database " . $db_name . "<br>"; 
    } catch(PDOException $e) {
        echo "<br>" . "Connection failed: " . $e->getMessage() . "<br>";
    }
    //#3
?>

这是JUnit测试类

public class Reflector {
public static <T> T initialize(Class<? extends T> clazz) {

    try {
        Object classInstance = clazz.newInstance();
        System.out.println("MainclassInstance: "+ classInstance.toString());

        for (Field field : clazz.getDeclaredFields()) {

            System.out.println(
             "\n### 1. For-Schleife\nclazz.getDeclaredFields().size(): " + clazz.getDeclaredFields().length);

            System.out.println("clazz.field: " + field.getName());

            //Class Object
            if (field.getType().isMemberClass()) {

                Object memberClassInstance = field.getType();      //Nested$FirstNested

                System.out.println("memberClassInstance: " + memberClassInstance.toString()); //Nested$FirstNested

                List<Field> memberClassFields = Arrays.asList(((Class<?>) memberClassInstance).getDeclaredFields());

                for (int memberFieldIndex = 0; memberFieldIndex < memberClassFields.size() - 1; memberFieldIndex++) {
                    System.out.println("meberClassField: " + memberClassFields.get(memberFieldIndex).getName());


                    //memberClassFields.get(memberFieldIndex).set(memberClassInstance, "nestedField");
                }
                //field.set(memberClassInstance, "MyObject");
                //field.set(classInstance, memberClassInstance);
            }

        }

        return (T) classInstance;

    } catch (SecurityException | IllegalArgumentException e) {
        e.printStackTrace();
    } catch (InstantiationException ex) {
        Logger.getLogger(Reflector.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        Logger.getLogger(Reflector.class.getName()).log(Level.SEVERE, null, ex);
    }

    return null;
}

这是数据类

public class ReflectorTest {

    @Test
    public void testInitializeNestedObject() {
        Nested actual = Reflector.initialize(Nested.class);

        assertNotNull(actual);
        assertNotNull(actual.nested1);
        assertTrue(actual.nested1 instanceof Nested.FirstNested);
        assertNotNull(actual.nested1.nestedField1);
        assertNotNull(actual.nested1.nestedField2);

        assertNotNull(actual.nested2);
        assertTrue(actual.nested2 instanceof Nested.SecondNested);
        assertNotNull(actual.nested2.nestedField3);
        assertNotNull(actual.nested2.nestedField4);
    }
}

2 个答案:

答案 0 :(得分:0)

问题在于,虽然您为容器类Nested创建实例,但您不会为所包含的类FirstNestedSecondNested创建实例。为了制作这类实例,您可以像这样更改您的课程

public static class Nested
{
    public static class FirstNested
    {
        public Object nestedField1;
        public Object nestedField2;
    }

    public static class SecondNested
    {
        public Object nestedField3;
        public Object nestedField4;
    }

    public FirstNested nested1;
    public SecondNested nested2;

}

您必须使内部类静态,以便可以通过反射轻松访问它们。然后,您必须实现(可能以递归方式)创建新实例并将这些实例注册到容器类实例。

像这样的东西

Object memberClassInstance = field.getType().newInstance();
field.set(classInstance, memberClassInstance);

或者你可以按照原样保留课程并使用类似的东西

Object memberClassInstance = field.getType().getConstructor(Nested.class).newInstance()

正如@CoronA在评论中提到的那样。有关如何实例化内部类的更多信息,请访问How to instantiate inner class with reflection in Java?

答案 1 :(得分:0)

正确的解决方案:

public class Reflector {
public static <T> T initialize(Class<? extends T> clazz) {

    try {
        Object classInstance = clazz.newInstance();
        System.out.println("MainclassInstance: " + classInstance.toString());

        for (Field field : clazz.getDeclaredFields()) {

            System.out.println(
                    "\n### 1. For-Schleife\nclazz.getDeclaredFields().size(): "
                    + clazz.getDeclaredFields().length);

            System.out.println("clazz.field: " + field.getName());


            //Class Object
            if (field.getType().isMemberClass()) {


                Object innerInstance = null;
                try {

                    Class<?> innerClass = Class.forName(field.getType().getName());
                    Constructor<?> ctor = innerClass.getDeclaredConstructor(classInstance.getClass());
                    innerInstance = ctor.newInstance(classInstance);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(Reflector.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(Reflector.class.getName()).log(Level.SEVERE, null, ex);
                } catch (NoSuchMethodException ex) {
                    Logger.getLogger(Reflector.class.getName()).log(Level.SEVERE, null, ex);
                }

                //###############
                Object memberClassInstance = field.getType();      //Nested$FirstNested

                System.out.println("memberClassInstance: " + memberClassInstance.toString()); //Nested$FirstNested

                List<Field> memberClassFields = Arrays.asList((innerInstance.getClass()).getDeclaredFields());

                for (int memberFieldIndex = 0; memberFieldIndex < memberClassFields.size() - 1; memberFieldIndex++) {
                    System.out.println("meberClassField: " + memberClassFields.get(memberFieldIndex).getName());
                    memberClassFields.get(memberFieldIndex).set(innerInstance, memberClassFields.get(memberFieldIndex).getName() + (memberFieldIndex+1));     
                }

                field.set(classInstance,innerInstance);

            }

        }

        return (T) classInstance;

    } catch (SecurityException | IllegalArgumentException e) {
        e.printStackTrace();
    } catch (InstantiationException ex) {
        Logger.getLogger(Reflector.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        Logger.getLogger(Reflector.class.getName()).log(Level.SEVERE, null, ex);
    }

    return null;
}