Josef said:
A single instance of ComplexKey might hold something like: a String, an
Integer and a Double. Simply put, the type of values you could find in
the fields of a primary key in a relational db.
That's as I guessed.
Yes, I think you're correct here.
A single instance of the ComplexKey can hold several different types in
its array, with the only common denominator being that they are
comparable to their own types - not to each other.
They all must implement Comparable, because otherwise the ComplexKey
itself can't become Comparable. (So changing the signature to accepting
an array of Objects would not be satisfactory).
Basically, the ComplexKey class is used for caching record keys from db
tables. In practice, this means that ComplexKeys are compared with other
ComplexKeys built with records from the same table (same order of class
instances in the keyValues array). To be more concrete, an instance of
ComplexKey holding a reference to a record in table "Orders" will only
be compared to other ComplexKeys referencing that same table, "Orders",
never to records in a table "Farmers". Attempting this would most likely
throw a run-time error, as two different tables are likely to have
different types of primary keys.
So why do the ComplexKey objects need to be Comparable? That's wholly
unnecessary for simple caching. Is there some other requirement here
that you haven't discussed yet?
Does this mean that I should create a subclass of ComplexKey for every
possible combination of field types in the primary key? Rather than
accepting an array with field values, each subclass would have a different
constructor:
public ComplexKey(Integer farmerId)
public ComplexKey(Integer farmerId, Integer Year, Integer speciesId)
This would create an explosion of classes and seems like a lot of
work... :-( And seem a lot less "generic" than what I'm doing today!
And it would not get you where you want to be without even more work
than you may realize. As I wrote before, you have a *fundamental* type
safety problem with your current code. Even if there were a way to
express them, the type constraints you want are not sufficient to
guarantee type safety for the elements of an array as you wish to use
them. On the other hand, type constraints sufficient to guarantee type
safety for your problem are stronger than you can work with. The same
would apply if you were using a List of the key fields instead of an
array. The only way I can see that you could obtain type safety is to
write ComplexKey subclasses that were completely independent, storing
the key fields in individual instance variables and not relying on a
common comparison engine. In principle one could write code to generate
such classes on the fly, but that's an extreme workaround for a minor
problem.
I encourage you, therefore, to take this opportunity to look at the
bigger picture. Do ComplexKey objects _really_ need to be Comparable?
My general rule of thumb is to rely on the DB to do what DBs are good
at, and sorting records is one of those things.