有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

获取相似对象属性的java通用方法

我有一个对象,它有几个数组作为字段。它的类大致如下所示:

public class Helper {
    InsuranceInvoices[] insuranceInvoices;
    InsuranceCollectiveInvoices[] insuranceCollectiveInvoices
    BankInvoices[] bankInvoices;
    BankCollectiveInvoices[] bankCollectiveInvoices;
}

所有发票类型都有一个相互标记界面发票
我需要获取所有发票,以便对其调用另一个方法

Helper helperObject = new Helper();
// ...

for (InsuranceInvoices invoice : helperObject.getInsuranceInvoices()) {
    Integer customerId = invoice.getCustomerId();
    // ...
}
for (BankInvoices invoice : helperObject.getBankInvoices()) {
    Integer customerId = invoice.getCustomerId();
    // ... 
}

// repeat with all array fields

问题是所有发票都只有共同的标记接口。方法getCustomerID()不是由交互接口或类定义的。由于给定的规范,我无法改变这种行为

for-each循环中的代码重复让我感到不舒服。我必须对四个不同数组中的所有invoice对象执行完全相同的操作。因此,每个循环有四个循环,这是不必要的代码膨胀

有没有一种方法可以编写通用(私有)方法?一个想法是:

private void generalMethod(Invoice[] invoiceArray){
    // ...
}

但是这需要四个检查实例,因为类Invoice不知道方法getCusomterId()。因此,我将一无所获;该方法仍将包含重复

我感谢所有可能的解决方案来推广这个问题


共 (3) 个答案

  1. # 1 楼答案

    这并不漂亮,但是您可以使用反射来查找getCustomerId{a1},然后再查找invoke(),参见Class.getDeclaredMethod()

    private void generalMethod(Invoice[] invoiceArray){
      try {
        for (Invoice invoice : invoiceArray) {
          Method getCustomerId = invoice.getClass().getDeclaredMethod("getCustomerId");
          getCustomerId.invoke(invoice);
        }
      } catch (Exception e) {
        // ...
      }
    }
    

    请注意这是未经测试的

  2. # 2 楼答案

    如果不允许通过添加自定义接口来更改正在处理的类。您可以做的最好的事情是使用具有所需属性的自定义类包装它们

    通过这种方式,您将拥有一个包含所有“不太好”代码的类,这些代码将您无法接触的类转换为符合适当和有用设计的好类

    例如,您可以有一个类WrappedInsuranceInvoice,它扩展了WrappedInsurace,并包含一个成员字段InsuranceInvoice。如果您不需要保留原始类,那么通过复制数据可以更好地关闭该类。例如,通过这种方式,您可能会丢失数组而改用列表

  3. # 3 楼答案

    概括问题的可能解决方案(从最佳到最差排序):

    使用包装类

    public class InvoiceWrapper {
        private String customerID;
        public String getCustomerID() {
            return customerID;
        }
        public InvoiceWrapper(BankInvoices invoice) {
           this.customerID = invoice.getCustomerID();
        }
        public InvoiceWrapper(InsuranceInvoices invoice) {
           this.customerID = invoice.getCustomerID();
        }
        // other constructors
    }
    

    Upd如果我理解正确,您需要对所有阵列中的ID执行一些操作。要使用InvoiceWrapper,还需要在Helper类中实现迭代器,它将遍历数组并为每个条目返回一个包装器。因此,您的代码无论如何都可以使用4个数组

    使用强制转换实例

    public class CustomerIdHelper {
        public static String getID(Invoice invoice) {
            if (invoice instanceof InsuranceInvoices) {
                return ((InsuranceInvoices) invoices).getCustomerID();
            } else if ...
        }
    }
    

    通过反射按名称调用方法

    public class CustomerIdHelper {
        public static String getID(Invoice invoice) {
            Method method = invoice.getClass().getDeclaredMethod("getCustomerId");
            return (String) method.invoke(invoice);
        }
    }