It's hard to explain my problem in words. I document it much better in the test/example code. But I'll take a swing at it anyways.

Basically, I have a list (1) of lists (2). Each inner list (2) is generic (much like ArrayList), but obviously contains "homogeneous" data, or rather, data each being an instance of the same class. The next list (2) will use a different class. The problem arises when I try to access one of those inner lists (2) from the outer list (1), at which point the type of the list is unknown <?>, and trying to access methods which use that type, e.g. add(?) are unusable.

The code below tries to catch the gist of what I'm ultimately trying to achieve, to demonstrate that I am using generics in a useful way, and to show the specific problem that I encounter that I am trying to overcome, as well as a hacked workaround using reflection which I'm currently using but desperately want to get rid of. As a result, it's a little lengthy, but a lot of it is just comments.

The code has enough comments to explain itself.

import java.util.ArrayList;
import java.util.TreeMap;
public class TestCase
{
//approximately 15 classes extend this class.
abstract class Resource //in my actual implementation, this is also a generic, but I stripped it for brevity
{
//contains some abstract methods
}
class ResourceList<R extends Resource> extends ArrayList<R>
{
private static final long serialVersionUID = 1L;
/** constructs a new resource of the list's type, adds it to this list, and returns it */
R add()
{
//method stripped for brevity
return null;
}
/** Creates a duplicate in this list and returns it. */
R duplicate(R res)
{
//method stripped for brevity.
return res;
}
}
//this is an example of a class that might extend Resource
class Gold extends Resource
{
//contains various properties of this instance of gold, such as perhaps carat and quantity
//also implements the abstract methods in Resource
}
/**
* Changed to ArrayList for simplicity's sake.<br />
* This is a mapping of resource types (e.g. GOLD_LIST) to resource lists (e.g. lists.get(0)).
* For example, the first list will contain all Gold. The second list will contain a different resource (e.g. all Wood), and so on.
* The number of lists is finite and constant, but depending on in-program parameters, may vary by 1 or 2 at setup.
*/
ArrayList<ResourceList<? extends Resource>> lists = new ArrayList<ResourceList<? extends Resource>>();
//indexes Gold into the mapping
static final int GOLD_LIST = 0;
////////////////////////////////////////////////////
// The code below is largely for example purposes //
////////////////////////////////////////////////////
void setup()
{
ResourceList<Gold> rl = new ResourceList<Gold>();
lists.add(GOLD_LIST,rl);
}
//this method demonstrates the problems I'm experiencing.
//In implementation, I have a method which "uses" similar code to the problem code below,
//but it is much too complex to introduce in this test case.
//Solve the problems below, and I can figure out the rest.
void test(int list)
{
//If I were to, for example, programmatically try to add Gold to its respective list, here's what happens:
Gold g = new Gold();
lists.get(GOLD_LIST).add(g);
//^ Error: The method add(capture#1-of ? extends TestCase.Resource) in the type
//ArrayList<capture#1-of ? extends TestCase.Resource> is not applicable for the arguments (TestCase.Gold)
//At this time, I don't actually know what kind of resource I'm dealing with.
//Whereas normally I'd be able to access the type of list (e.g. Gold List) explicitly,
//here I have to access it programmatically (via the mapping).
Resource res = lists.get(list).add();
//^ works fine
Resource r1 = lists.get(list).duplicate(res);
//^ Error: The method duplicate(capture#3-of ? extends TestCase.Resource) in the type
//TestCase.ResourceList<capture#3-of ? extends TestCase.Resource> is not applicable for the arguments (TestCase.Resource)
//Current ugly-as-hell workaround that I want to get rid of
ResourceList<?> rl = lists.get(list);
Resource r2 = (Resource) rl.getClass().getMethod("duplicate",Resource.class).invoke(rl,res);
}
public static void main(String[] args)
{
TestCase tc = new TestCase();
tc.setup();
tc.test(GOLD_LIST);
}
}

The problem, as I already said, is that the generic type gets lost and becomes <?>, and you can't really pass an argument to a method that's expecting "?".
My question, then, is how would I access the duplicate method programmatically? Preferably some method that doesn't use the hacked reflection shown above.

jtahlborn wrote:
you can't do what you want, the main problem being that your top-level list is heterogeneous. the best you could do would be to declare:

The issue also comes down to trying to assert run-time assumptions at compile-time. At compile time, who's to know that the second list is Gold typed? Why couldn't "somebody else" have set the second element to a List<Silver>?

@OP, one way it is possible to get around this is to abandon the List interface and encapsulate the type-unsafety to a point where you can guarantee its runtime safety. Something like this: