<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div class="markdown-here-wrapper" data-md-url="" style="" markdown-here-wrapper-content-modified="true">
<p style="margin: 0px 0px 1.2em !important;">On 29/03/2023 14:14,
Archie Cobbs wrote:</p>
<p style="margin: 0px 0px 1.2em !important;"></p>
<div class="markdown-here-exclude">
<p></p>
<blockquote type="cite" cite="mid:CANSoFxuv0ASS=0MtnT3Jz=oW3RELg0N72LeyTzFMmMG9fEtxWA@mail.gmail.com">
<div>Regarding that problem, would it work to just add
"workaround" methods like this?</div>
<div><br>
</div>
<div> public static <T extends Enum<T>>
EnumSet<T> noneOfGeneric(Class<? extends T>
klass)</div>
<div><br>
</div>
<div>Even though klass has type Class<? extends T>, at
compile time, you're not going to be able to specify any
Class constant other than the top enum class, so no problem
there, and at runtime, this method could do introspection to
find the top enum class (if necessary; unlikely) and then
use that.</div>
</blockquote>
<p></p>
</div>
<p style="margin: 0px 0px 1.2em !important;"></p>
<p style="margin: 0px 0px 1.2em !important;">I don't think that
would help much. To show why, let’s step back a bit, and let's
ignore enums completely.<br>
</p>
<p style="margin: 0px 0px 1.2em !important;">Consider the
following recursive generic type declaration:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">class Foo<X extends Foo<X>> { ... }
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">Now let’s define a
container type for our Foos:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code class="hljs language-java" style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;display: block; overflow-x: auto; padding: 0.5em; color: rgb(51, 51, 51); background: rgb(248, 248, 248) none repeat scroll 0% 0%; -moz-text-size-adjust: none;"><span class="hljs-class"><span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">class</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;color: rgb(68, 85, 136); font-weight: bold;">Box</span><<span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;color: rgb(68, 85, 136); font-weight: bold;">X</span> <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">extends</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;color: rgb(68, 85, 136); font-weight: bold;">Foo</span><<span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;color: rgb(68, 85, 136); font-weight: bold;">X</span>>> </span>{
<span class="hljs-function">X <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">get</span><span class="hljs-params">()</span></span>;
<span class="hljs-function"><span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">void</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">set</span><span class="hljs-params">(X x)</span> </span>{ ... }
}
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">Given these
declaration, the following types are <strong>not</strong>
well-formed types:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">Box<Foo>
Box<Foo<?>>
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">The following is
legal:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">Box<? extends Foo>
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">But that is also a
type that has significantly different characteristics from the
ones above - e.g. you can’t call <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Box::set</code>
on it. So, even before getting to generic methods accepting
Foos, we have a much more fundamental problem: we can't even
express the type of a variable of type <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Box<Foo></code>
in the type-system (!!).<br>
</p>
<p style="margin: 0px 0px 1.2em !important;">What we realized was
that JEP 301 rubs exactly againt this problem (just s/Foo/Enum
and s/Box/EnumSet) - which means code using non-generic enums
doesn’t have a clear migration path towards generified enums.</p>
<p style="margin: 0px 0px 1.2em !important;">Maurizio</p>
<div title="MDH:PHA+PGJyPjwvcD48ZGl2IGNsYXNzPSJtb3otY2l0ZS1wcmVmaXgiPk9uIDI5LzAzLzIwMjMgMTQ6MTQsIEFyY2hpZSBDb2JicyB3cm90ZTo8YnI+PC9kaXY+PGJsb2NrcXVvdGUgdHlwZT0iY2l0ZSIg
Y2l0ZT0ibWlkOkNBTlNvRnh1djBBU1M9ME10blQzSno9b1czUkVMZzBONzJMZXlUekZNbU1HOWZF
dHhXQUBtYWlsLmdtYWlsLmNvbSI+PGRpdj5SZWdhcmRpbmcgdGhhdCBwcm9ibGVtLCB3b3VsZCBp
dCB3b3JrIHRvIGp1c3QgYWRkICJ3b3JrYXJvdW5kIiBtZXRob2RzIGxpa2UgdGhpcz88L2Rpdj48
ZGl2Pjxicj48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBwdWJsaWMgc3Rh
dGljICZsdDtUIGV4dGVuZHMgRW51bSZsdDtUJmd0OyZndDsgRW51bVNldCZsdDtUJmd0OyBub25l
T2ZHZW5lcmljKENsYXNzJmx0Oz8gZXh0ZW5kcyBUJmd0OyBrbGFzcyk8L2Rpdj48ZGl2Pjxicj48
L2Rpdj48ZGl2PkV2ZW4KIHRob3VnaCBrbGFzcyBoYXMgdHlwZSBDbGFzcyZsdDs/IGV4dGVuZHMg
VCZndDssIGF0IGNvbXBpbGUgdGltZSwgeW91J3JlCiBub3QgZ29pbmcgdG8gYmUgYWJsZSB0byBz
cGVjaWZ5IGFueSBDbGFzcyBjb25zdGFudCBvdGhlciB0aGFuIHRoZSB0b3AgCmVudW0gY2xhc3Ms
IHNvIG5vIHByb2JsZW0gdGhlcmUsIGFuZCBhdCBydW50aW1lLCB0aGlzIG1ldGhvZCBjb3VsZCBk
byAKaW50cm9zcGVjdGlvbiB0byBmaW5kIHRoZSB0b3AgZW51bSBjbGFzcyAoaWYgbmVjZXNzYXJ5
OyB1bmxpa2VseSkgYW5kIAp0aGVuIHVzZSB0aGF0LjwvZGl2PjwvYmxvY2txdW90ZT48cD5MZXQn
cyBzdGVwIGJhY2sgYSBiaXQuPC9wPjxwPkxlJ3MgaWdub3JlIGVudW1zIGNvbXBsZXRlbHksIGFu
ZCBjb25zaWRlciB0aGUgZm9sbG93aW5nIHJlY3Vyc2l2ZSBnZW5lcmljIHR5cGUgZGVjbGFyYXRp
b246PC9wPjxwPmBgYDxicj5jbGFzcyBGb28mbHQ7WCBleHRlbmRzIEZvbyZsdDtYJmd0OyZndDsg
eyAuLi4gfTxicj5gYGA8YnI+PC9wPjxwPk5vdyBsZXQncyBkZWZpbmUgYSBjb250YWluZXIgdHlw
ZSBmb3Igb3VyIEZvb3M6PC9wPjxwPmBgYGphdmE8YnI+Y2xhc3MgQm94Jmx0O1ggZXh0ZW5kcyBG
b28mbHQ7WCZndDsmZ3Q7IHs8YnI+Jm5ic3A7ICZuYnNwOyBYIGdldCgpOzxicj4mbmJzcDsgJm5i
c3A7IHZvaWQgc2V0KFggeCkgeyAuLi4gfTxicj59PGJyPmBgYDxicj48L3A+PHA+R2l2ZW4gdGhl
c2UgZGVjbGFyYXRpb24sIHRoZSBmb2xsb3dpbmcgdHlwZXMgYXJlICoqbm90Kiogd2VsbC1mb3Jt
ZWQgdHlwZXM6PC9wPjxwPmBgYDxicj5Cb3gmbHQ7Rm9vJmd0Ozxicj5Cb3gmbHQ7Rm9vJmx0Oz8m
Z3Q7Jmd0Ozxicj5gYGA8YnI+PC9wPjxwPlRoZSBmb2xsb3dpbmcgaXMgbGVnYWw6PC9wPjxwPmBg
YDxicj5Cb3gmbHQ7PyBleHRlbmRzIEZvbyZndDs8YnI+YGBgPGJyPjwvcD48cD5CdXQgdGhhdCBp
cyBhbHNvIGEgdHlwZSB0aGF0IGhhcyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBjaGFyYWN0ZXJp
c3RpY3MgZnJvbSB0aGUgb25lcyBhYm92ZSAtIGUuZy4geW91IGNhbid0IGNhbGwgYEJveDo6c2V0
YCBvbiBpdC48L3A+PHA+U28sIGJhY2sgdG8gSkVQIDMwMSwgd2hhdCB3ZSByZWFsaXplZCBpcyB0
aGF0IHdlIHJ1YmJlZCBhZ2FpbnN0IGV4YWN0bHkgdGhpcyBwcm9ibGVtIChqdXN0IHMvRm9vL0Vu
dW0gYW5kIHMvQm94L0VudW1TZXQpIC0gd2hpY2ggbWVhbnMgY29kZSB1c2luZyBub24tZ2VuZXJp
YyBlbnVtcyBkb2Vzbid0IGhhdmUgYSBjbGVhciBtaWdyYXRpb24gcGF0aCB0b3dhcmRzIGdlbmVy
aWZpZWQgZW51bXMuPGJyPjwvcD48cD5NYXVyaXppbzxicj48L3A+" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;"></div>
</div>
</body>
</html>