第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

有沒有比使用反射在繼承層次結(jié)構(gòu)中通過工廠方法實例化元素更好的方法?

有沒有比使用反射在繼承層次結(jié)構(gòu)中通過工廠方法實例化元素更好的方法?

一只名叫tom的貓 2023-03-02 10:06:42
我構(gòu)建了一個繼承層次結(jié)構(gòu),其中一堆具體類繼承自抽象超類A。A具有一個強(qiáng)制屬性 Stringa和一個可選的 Mapb和 xml 模型規(guī)范的模型元素。和a中可能的鍵值對b都是 jaxp.NamedNodeList 的一部分。a因此,要設(shè)置和 的值,b我總是需要遍歷列表并檢查當(dāng)前屬性是否具有名稱“id”,并分別設(shè)置 的值a或?qū)㈡I值對添加到b. 顯然有人想將其外包給工廠方法等。但是,在抽象超類中實現(xiàn)靜態(tài)工廠方法A顯然是不夠的,因為通過返回 A 的新實例,我需要在使用工廠方法創(chuàng)建它時將實例化向下轉(zhuǎn)換為具體元素。所以我想出了一個使用反射的解決方案,但我真的很不安全,因為沒有更簡單的方法來解決一個看起來如此普遍的問題。有沒有更簡單的解決方案?這是我的工廠模式,ClassCastException當(dāng)將 A 向下轉(zhuǎn)換為 B 時,會產(chǎn)生這樣的結(jié)果SubclassB b = (SubclassB) AbstractSuperClassA.createWith(attributes);:public static AbstractSuperClassA createWith(NamedNodeMap attributes) {    Map<String, String> attributeMap = new HashMap<>();    String a= null;    for (int i = 0; i < attributes.getLength(); i++) {        if (attributes.item(i).getNodeName().equals("id")) {            a = attributes.item(i).getNodeValue();        }        attributeMap.put(attributes.item(i).getNodeName(), attributes.item(i).getNodeValue());    }    if (a == null) {        // throw RuntimeException    }    return new AbstractSuperClassA (identifier, attributeMap);}這是通用的反射實現(xiàn):public static <T extends AbstractSuperClassA > T init(NamedNodeMap attributes, Class<T> clazz) {    Map<String, String> attributeMap = new HashMap<>();    String a= null;    for (int i = 0; i < attributes.getLength(); i++) {        if (attributes.item(i).getNodeName().equals("id")) {            a = attributes.item(i).getNodeValue();        }        attributeMap.put(attributes.item(i).getNodeName(), attributes.item(i).getNodeValue());    }    if (a== null) {        // throw RuntimeException    }    try {        Constructor<T> constructor = clazz.getConstructor(String.class);        T newElement = constructor.newInstance(a);        newElement.setAttributes(attributeMap);        return newElement;    } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {        log.error(e.getMessage(), e);    }    return null;}
查看完整描述

1 回答

?
藍(lán)山帝景

TA貢獻(xiàn)1843條經(jīng)驗 獲得超7個贊

您的init方法似乎需要一種方法來基于單個值創(chuàng)建給定類的實例。String


在這種情況下,您不需要反思。無需傳入Class實例化和初始化,您可以實現(xiàn)一種“策略模式”形式,其中策略是可變的并且僅定義如何創(chuàng)建新的、ID 初始化的對象。


在 Java 8 及更高版本中,您可以為此使用函數(shù)式接口和 Lambdas:


private <T extends AbstractSuperClassA > T init(NamedNodeMap attributes, Function<String,T> creator) {

  ...

  T newElement = creator.apply(identifier);

  ...

}

然后適當(dāng)?shù)厥褂盟?,例?/p>


B someB = init(attrs, B::new);

C someC = init(attrs, id -> {C c = new C(); c.setId(id); return c;});

...

然而,問題是您如何決定應(yīng)該實例化哪個具體類。在任何情況下,該邏輯都必須在某個地方進(jìn)行編碼,因此可能有更好的方法來連接邏輯以收集值和初始化新實例的邏輯。


是否要求實例id在構(gòu)造函數(shù)中接收?還是可以稍后設(shè)置?


查看完整回答
反對 回復(fù) 2023-03-02
  • 1 回答
  • 0 關(guān)注
  • 108 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號