Fully agree... unless you embrace unchecked casts (e.g. if your impl cast to X and suppresses the warning, the program compiles).

Which is what Kevin was trying to say: having a generic method that doesn't use its type-variable in its parameters can be a bit of a smell, in the sense that implementors can forget that they don't have much control over what the type parameter might be inferred to.

All this goes back to my original point: we can't express a method that returns a conjunction of two types today; the alternative is to declare a new type just for that (but some of the arguments originally discussed in this thread apply: e.g. I might not have a great name for it, nor a desire for actually naming it), or resort to unchecked generic dark arts (which, as you and Kevin point out, 95% is subtly broken).

Maurizio

On 07/10/2021 22:25, Alan Malloy wrote:
You can't actually do this: that signature is a promise to return an instance of /any/ class implementing those interfaces, not /some/ class implementing them. If you try to implement your getCloseableFoo method, you'll find that no implementation compiles. For example:

final class tmp {
  static <X extends AutoCloseable & Serializable> X getX() {
    class Impl implements AutoCloseable, Serializable {
      public void close() {}
    }
    return new Impl();
  }
}

tmp.java:8: error: incompatible types: Impl cannot be converted to X
    return new Impl();
           ^
  where X is a type-variable:
    X extends AutoCloseable,Serializable declared in method <X>getX()

This is because some caller may define their own MyImpl class implementing those interfaces, and then write MyImpl i = getX(), instantiating X to MyImpl, and your method doesn't know how to build such an object.

On Thu, Oct 7, 2021 at 7:37 AM Maurizio Cimadamore <maurizio.cimadam...@oracle.com <mailto:maurizio.cimadam...@oracle.com>> wrote:

    But I'm puzzled by the fact that programmers can, in a way, do
    something similar to the above with a generic method:

    <X extends Foo & AutoCloseable> X getCloseableFoo();

    Which kind of works, but it's quite an horrible hack (you
    introduce a type parameter you don't need - which means compiler
    will try to infer types, etc.)

Reply via email to