Unfortunately, as of API version 26, SFDC removed parameterized interfaces.

However, it is relatively easy to create new interfaces and set the version as 25.

So, to take the example from Parameterized Interfaces - what are they?, I can make the Pair and DoubleUp interfaces, as "version 25", but then I can make the StringPair itself as "version 38" (for example).

The StringPair compiles and functions as expected.

While one might argue that this would not be idiomatic Apex and that newer developers might not be able to find documentation to support it (if they don't use stackechange, but who doesn't?), I'm wondering from a technical perspective, what problems should I expect?

  • Do issues related to instanceof also effect Parameterized types?
  • Are there performance problems?
  • Are there known compatibility issues when such interfaces might be come into contact with newer features or objects/sObjects which are dependent upon newer features?

To be clear, I'm not suggesting putting all the code or any other code into older API versions, just specifically the parameterized interfaces.

  • 3
    I would add to your list of concerns that any bugs already existing or that you find are unlikely to get fixed. This is the sort of feature that I hope gets re-introduced now there is the new'ish Apex compiler.
    – Keith C
    May 15 '18 at 11:21
  • In one of reviews salesforce recommendation for us was to not keep the code on more than 3 api versions. latest ones.
    – RedDevil
    May 15 '18 at 11:23
  • Depending on what your class does you may encounter this success.salesforce.com/issues_view?id=a1p30000000T0tvAAC May 15 '18 at 14:12

Do issues related to instanceof also effect Parameterized types?

Yes. The instanceof behavior for these almost certainly has edge cases or areas where there is no defined behavior.

Are there performance problems?

There have been in the past. I'm not aware of any ongoing performance problems, but there's also very little use of parameterized types in Apex, and as they are no longer supported net-new adoption finding performance issues would be unlikely to be a priority.

Remember that by being on APIv25 you're opting in to dozens of years old bugs in these classes. Many Apex bugs have to be fixed as versioned due to somebody somewhere relying on the improper behavior, leading to the fixes being versioned changes.

There are known issues with how managability rules (what prevents you from breaking customers in managed packaged code). Absolutely do not do this for a managed package.

I would still strongly discourage the use of this in non-managed code. Any support for issues found will be limited.

  • Good response, but to be clear, I'm not talking of putting all the code in APIv25, but rather (hypothetically speaking) to just put the parameterized interfaces in APIv25. Also, unless SFDC is using some secret sauce we can't access, Maps, Lists, Sets, Iterables, Iterators, and Batchables are all using parameterized types. May 15 '18 at 21:39
  • @Brian Kessler I guess I should mention that I'm the PM for Apex and that yes, we are absolutely using secret sauce you can't access for those. It's part of the reason you can't subclass Apex collections today. May 25 '18 at 15:03
  • Cheers for the clarification. Any chance of making the "secret sauce" public in the foreseeable future? May 25 '18 at 17:34
  • 2
    @BrianKessler certainly been discussed, and we see the need for it. There are some challenges at making it safe in edge cases that make it unlikely in the short term. Jun 3 '18 at 19:27
  • I'm curious of your use of the word "safe" in this context. Can you discuss the risks and challenges that you see with making such a feature public? Admittedly I'm not a security expert, but I do like to learn about it and I pride myself in out-of-the-box thinking... Jun 4 '18 at 23:05

For "Shits and giggles", I decided to try transcribing some Java code to Apex to see how (ab)using parameterized types might hold up in more complicated scenario.

Perhaps either my understanding or my transcription is incorrect since even version 25 doesn't support an interface like:

public interface TaxStrategy<P extends TaxPayer> {
  public double extortCash(P p);

So, I had to settle for making the interface simply:

public interface TaxStrategy<TaxPayer> {
  public double extortCash(TaxPayer taxPayer);


public interface TaxStrategy<P> {
  public double extortCash(P p);

Either way, the Apex compiled, but when I tried to anonymously execute my code, the attempt failed with:

DEBUG LOG apex.bytecodeinterpreter.InterpreterRuntimeException: Made lookup for method that does not exist on this type (TAX_XTOR_EmployeeTaxStrategy). MethodRef = void.TAX_XTOR_TaxStrategyIntf$$lTAX_PAYR_TaxPayerIntf$$r_iextortCash(java/lang/Object)java/lang/Object Error Id: 1723891688-25942 (1784837775)

If I added debug logs, I could verify the code executed until the correct strategy was instantiated, but suddenly died when the extortCash() was executed. Interestingly, this is actually a silent failure, as the log doesn't include the exception and has a status of "Success".

While it is possible that my interpretation from Java to Apex is incorrect, that there are silent failures and SFDC makes the code very difficult to debug is a big blocker in my book.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.