Overloading Java function with List<> parameter

前端 未结 6 1281
猫巷女王i
猫巷女王i 2021-02-02 15:19

I have 2 classes

public class Customer{
  ...
  public String getCustomerNumber();
  ...
}

public class Applicant{
   ....
   private Customer c;
   public Cust         


        
相关标签:
6条回答
  • 2021-02-02 15:35

    Generics have what is known as type erasure - List<Customer> and List<Applicant> are the same type, the compiler just places compile-time restrictions on what you can do with them.

    You could check the type of the first object in the list and call a (differently-named) internal method based on that.

    0 讨论(0)
  • 2021-02-02 15:37

    Use array instead.

    public void processCustomerNumbers(Customer[] custList)
    ...
    
    public void processCustomerNumbers(Applicant[] appList)
    ...
    

    When you try to call these methods with a list, convert the list to array:

    List<Customer> customers;
    List<Applicant> applicants;
    ...
    processCustomerNumbers(customers.toArray(new Customer[]{});
    processCustomerNumbers(applicants.toArray(new Applicant[]{});
    
    0 讨论(0)
  • 2021-02-02 15:38

    The thing about generics in Java is that generic types are erased at runtime, so both of these methods compile to the same signature. You will need to have separate method names, or check the type of the list elements at runtime.

    0 讨论(0)
  • 2021-02-02 15:40

    Before coming into the method names , the class hierarchy is little bit confusing...

    public class Customer{          
      ...          
      public String getCustomerNumber();          
      ...          
    }          
    
    public class Applicant{          
       ....          
       private Customer c;          
       public Customer getCustomer(){ return c; }          
       ...          
    }    
    

    Why should applicant and Customer be different objects ? Can you tell the relation between these objects ?

    0 讨论(0)
  • 2021-02-02 15:52

    If you make both classes implement a common interface,

    interface CustomerNumber {
        String getCustomerNumber();
    }
    
    public class Customer implements CustomerNumber {
      ...
      public String getCustomerNumber();
      ...
    }
    
    public class Applicant implements CustomerNumber {
       ....
       private Customer c;
       public Customer getCustomer() { return c; }
       public String getCustomerNumber() { return getCustomer().getCustomerNumber(); }
       ...
    }
    

    then you might be able to do what you want with just a single method:

    public void processCustomerNumbers(List<? extends CustomerNumber> appList) {
        for (Customer c: appList) {
            processCustomerNumber(c.getCustomerNumber());
        }
    }
    
    0 讨论(0)
  • 2021-02-02 15:52

    One way to workaround this issue would be to define custom list types like this:

    class CustomerList extends ArrayList<Customer> {
        ...
    }
    
    class ApplicantList extends ArrayList<Applicant> {
        ...
    }
    

    Then the following overloading would be legal:

    public void processCustomerNumbers(CustomerList custList)
    
    public void processCustomerNumbers(ApplicantList appList)
    

    However, I don't think that this would be a good idea. For a start, it hardwires particular implementation classes into your application's APIs.

    A better approach is to define a common interface for Customer and Applicant that allows you to process them with one processCustomerNumbers method. (As described at length in other answers.)

    0 讨论(0)
提交回复
热议问题