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.)