簡體   English   中英

根據類型創建不同的對象

[英]Create different objects depending on type

我有一個數據庫表,其中包含名為type的列。 對於數據庫列中的每一行,我必須根據類型創建一個對象。 目前,我使用if else語句:

if (type.equals("object1")){
    Object1 object1 = new Object1();
}
else if (type.equals("object2")){
    Object2 object2 = new Object2();
}

使用枚舉會更好一些,因為類型的數量是有限的,但是是否有可能讓對象的創建取決於String的值呢?

我樂於接受可能以不同於我嘗試的其他方式解決問題的建議。

您可以創建從StringClass的映射,並使用newInstance 但是,這依賴於無參數構造函數的存在。

import java.util.*;

class Test {
    public static void main(String[] args) throws Exception {
        Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
        classes.put("object1", Object1.class);
        classes.put("object2", Object2.class);

        String type = "object2";

        Object obj = classes.get(type).newInstance();

        //...
    }
}

class Object1 { ... }

class Object2 { ... }

您可以使用

Object o = Class.forName(type).newInstance();

如果您有一個int和兩個Strings作為參數,則需要。

Object o = Class.forName(type)
                .getConstructor(int.class, String.class, String.class)
                .newInstance(intValue, string1, string2);

另一種可能性是使用工廠方法

Object o = getClass().getMethod("create_" + type).invoke(null);

static Object1 create_object1() {
     return new Object1(/* with args */);
}

static Object2 create_object2() {
     return new Object2(/* with other args */);
}

但最靈活的方法可能是使用開關

Object o;
switch(type) { // in Java 7
    case "object1": o = new Object1(); break;
    case "object2": o = new Object2(); break;

更加優雅的是在Java 8中使用閉包。

http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html

package main;

import java.util.ArrayList;
import java.util.List;

public class TempClass {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        List<Class> classes = new ArrayList<Class>() {{
            add(Class.forName("main.Object1"));
            add(Class.forName("main.Object2"));
        }};
        for (Class aClass : classes) {
            Object o = aClass.newInstance();
        }
    }
}


package main;

public class Object1 {
    public Object1() {
        System.out.println("Object1");
    }
}


package main;

public class Object2 {
    public Object2() {
        System.out.println("Object2");
    }
}

我認為,使用switchif語句會強制您對各種選項進行硬編碼,因此您將獲得一個不太靈活的解決方案。

我總是喜歡編寫可擴展以用於將來的軟件開發的代碼。

因此,我建議您使用Object o = Class.forName(type).newInstance(); 在數據庫中輸入要實例化的類的名稱,並在需要時添加自定義標簽。

編輯

如果必須將一些參數傳遞給必須實例化的類的構造函數,則可以使用Constructor.newInstance()代替Class.newInstance(); 並使用Constructor對象實例化該類,例如:

Class myClass = Class.forName(type);

// get the constructor you need specifying parameters type 
Constructor constructor = myClass.getConstructor(String.class);

Object myObject = constructor.newInstance("constructor-arg");

如果所討論的類是繼承層次結構的一部分,而您恰巧使用了某種映射工具/框架(例如Hibernate或iBATIS / MyBatis),則它可能包括一種配置所謂的鑒別器的方法。

然后,您可以將“類型”列配置為“描述符”列,並將支持的值映射到您的類。 然后,當您從數據庫中檢索對象時,框架將為您實例化適當的類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM