Re: SOLVED! (Once again problems with wildcards/generic methods)
- From: Hendrik Maryns <hendrik_maryns@xxxxxxxxxxxxx>
- Date: Thu, 02 Mar 2006 21:35:05 +0100
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message
Hendrik Maryns uitte de volgende tekst op 03/01/2006 01:29 PM:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message
Hendrik Maryns schreef:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message
Hendrik Maryns schreef:
-----BEGIN PGP SIGNED MESSAGE-----I should add to this that I do not need arrangedStates to be anything
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message
Hi,
I have successfully applied generics a few times now, but once again, it
gets a bit more complicated, and Eclipse?s error messages are a bit too
cryptic.
So I have this method
public <T extends State> List<Set<List<T>>> arrangeStates(Set<T> states)
Here, I need the parameter T, because I want to be able to give subtypes
of State to the method, and get a result with the same subtypes (as in
Sun?s Generics Tutorial: parametrised methods should be used if you want
to express a relation between the types of the arguments and/or return
type.) I had to introduce the T, because I want to invoke the method
with a subtype of State (worked fine with State before).
Now another method,
public List<Set<FunctionInputTuple>> sortForArities(Set<? extends State>
states)
invokes arrangeStates like so:
List<Set<List<State>>> arrangedStates = this.arrangeStates(states);
and then goes on doing stuff with it. Here, I did not use a type
parameter, as wildcards are sufficient. But as the knowledgeable will
have noticed, the above line does not compile. How can I change it such
that I can invoke arrangeStates on Set<? extends State>?
The compiler message is this:
Error Type mismatch: cannot convert from List<Set<List<capture-of ?
extends State>>> to List<Set<List<State>>> Signature.java
Eclipse?s Quick Fix proposes to change the type of arrangedStates to
List<Set<List<? extends State>>>, but that gives another warning, and
its suggestions stay the same...
more specific than a list of sets of lists of states (indeed, this is
something cartesian-product like). Whether they are a subtype of states
is not important.
Hi all,
After reading in the very interesting Java Generics FAQ from Angelika
Langer, I finally found the answer in the article about multilevel
wildcards:
http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#What%20do%20multilevel%20wildcards%20mean?
or http://tinyurl.com/h3j8y.
Also the part about Type System
http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#Type%20System
explains what happens in nested type arguments (stuff like List<?
extends Set<? super Long>>).
Roedy, might be something interesting to link to...
The problem is that the type arguments are nested, and wildcard capturing.
Anyway, the solution was to make sortForArities a parametrised method,
like this:
public <T extends State> List<Set<FunctionInputTuple>> sortForArities(
Set<T> states) {
List<Set<SignatureSymbol>> sortSyms = getSymbolsSorted();
List<Set<FunctionInputTuple>> result = new
ArrayList<Set<FunctionInputTuple>>();
List<Set<List<T>>> arrangedStates = this.arrangeStates(states);
for (Set<SignatureSymbol> set : sortSyms) {
Set<FunctionInputTuple> aritySet = new HashSet<FunctionInputTuple>();
result.add(aritySet); // to the end!
for (SignatureSymbol symbol : set) {
for (List<T> stateArr : arrangedStates.get(symbol
.getArity())) {
try {
aritySet.add(FunctionInputTuple.getInstance(symbol,
stateArr));
} catch (FunctionArgumentsMismatchException e) {
// should not occur
}
}
}
}
return result;
}
That works. I have to think a bit more about why exactly this is
necessary and whether this would be possible with wildcards, because
only seeing the method signature, it seems unnecessary to use the
generic method form. This should be possible with wildcards. This
breaks encapsulation: by changing this into a generic method, I give
away that I cannot implement it with wildcards, which says something
about the constructs used.
Forget that. The trick is, to make the method above private, then
invoke that one from the public one which uses wildcards. A bit
unclean, but works and the only way. See http://tinyurl.com/o4a82, in
Angelika?s FAQ again.
Thanks to all, and to Angelika Langer specifically.again.
H.
--
Hendrik Maryns
==================
www.lieverleven.be
http://aouw.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
iD8DBQFEB1b5iOEY3xKMFEERAmSwAKCKKjEuc1rLy1IrPEtxcoYc2VYM0QCgkuBf
0eZg4i3JZS4e6Fr6jC2Zlgs=
=rPKM
-----END PGP SIGNATURE-----
.
- References:
- SOLVED! (Once again problems with wildcards/generic methods)
- From: Hendrik Maryns
- SOLVED! (Once again problems with wildcards/generic methods)
- Prev by Date: Re: Problem with Widcards
- Next by Date: Refreshing a tree in an IFrame
- Previous by thread: SOLVED! (Once again problems with wildcards/generic methods)
- Next by thread: Filling an array with values from the user
- Index(es):
Relevant Pages
|
Loading