Skip to main content
Aidan Harding (Aquiva Labs) 님이 Generics in Apex에 글을 올렸습니다

It would be really useful to support covariant return types alongside this. That way, we can have generics in a class hierarchy where fluent methods can return the correct types. 

 

For example, consider an example in Java where we want to define a custom list type with a generic type T (MyList<T> in the example).  There may well be things that we want to do differently when we know that we have a list of SObjects (for example, have a method to do a database update). 

 

In the example below, the fluent method, add(), returns "this". SObjectList can override add() to return itself rather than a MyList, keeping the right context as we call add() a number of times. 

 

That pattern is not currently possible in Apex because it does not support covariant return types (https://ideas.salesforce.com/s/idea/a0B8W00000GdXOCUA3/support-covariant-return-types-in-apex). 

 

public class Main {

public static void main(String[] args) {

MyList<Integer> intList = new MyList<Integer>()

.add(3)

.add(5);

System.out.println("ints: " + intList.toString());

SObjectList<Account> accountList = new SObjectList<Account>()

.add(new Account("Foo"))

.add(new Account("Bar"))

.doUpdate();

System.out.println("SObjects: " + accountList.toString());

}

static class SObject {

@Override

public String toString() {

return "Hi, I'm an SObject";

}

}

static class Account extends SObject {

private final String name;

public Account(String name) {

this.name = name;

}

@Override

public String toString() {

return "Account Name: " + name;

}

}

static class MyList<T> {

private final List<T> theList;

public MyList() {

theList = new ArrayList<T>();

}

public MyList<T> add(T toAdd) {

theList.add(toAdd);

return this;

}

public String toString() {

return theList.stream().map(Objects::toString).collect(Collectors.joining(", "));

}

}

static class SObjectList<T extends SObject> extends MyList<T> {

public SObjectList() {

super();

}

@Override

public SObjectList<T> add(T toAdd) {

super.add(toAdd);

return this;

}

public SObjectList<T> doUpdate() {

System.out.println("Do a database update!");

return this;

}

}

}

0/9000