This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I'm trying to convert an original int-based Matrix class into a generic Matrix class. The int-based code contains this initializer:
However, when I try to convert it to a generic format, I run into problems:
I've already google this a bit and have learned that for the sake of backward-compatibility, Java doesn't support generic arrays. I've found suggestions to use Array.newInstance, but I can't get find the right permutation of the code to make it work; e.g.:
There are MULTIPLE references to an article by Neal Gafter at the Sun site throughout the web (even elsewhere here at this site), BUT THAT LINK IS DEAD, so I can't access what might be the golden article I need.
If anyone can help me construct the correct equivalent code for:
There are two ways to solve this:
1) data = (T)new Object[rows][columns];
2) declare data as an Object, then cast to T when retrieving elements from the matrix.
Yes, both will generate compiler warnings (note: warnings, not errors). That's because the compiler can no longer verify that the data is going to be correct. Both solutions will lead to errors if some other code puts a non-T into the array. Keep data private and you get to control that, thereby making the warned cast safe and therefore ignorable.
For your info, ArrayList uses the second approach.
1) Shouldn't rows and columns still be ints? Those are the dimensions, not matrix elements.
2) The unchecked cast is a warning, not an error. I warned you about that. To prevent this warning (if you've ensured that all access to it is safe and secured) you can use @SuppressWarnings:
Joined: Jan 02, 2011
Ah! Thank you! I'm closer now, but I've run into a problem in the next step, adding together two matrices.
I'm not clear on how to cast references to the arrays for arithmetic operations; the IDE complains:
Tom Brodhead wrote:I'm not clear on how to cast references to the arrays for arithmetic operations; the IDE complains:
The operator + is undefined for the argument type(s) java.lang.Object, java.lang.Object
How do I reference the generic type that being employed? I've tried pre-pending (T) before each array reference, but it doesn't work.
+ is only available for Strings and the numeric primitive types (including char) (and their wrappers because of auto unboxing). For anything else you'll need to use methods. In this case you have two options:
1) use a common interface with a method for adding. You must then limit T to that interface. That excludes existing classes like Integer, Long and Double though.
2) use a set of interfaces for the operations. Your add method then also takes an instance of such an interface.
Granted, it's not nice looking, but at least you'll be able to use Integer etc.
Also, am I right to use <?> when the type isn't known?
Right. But you don't want that in this method, because you don't want to add an apple matrix to a pear matrix, do you? You want to at least limit them to some common type; that's what T is in my code. Note that this T is different from the class generic type.
Joined: Jan 02, 2011
Wow, thanks! However, the IDE underlines the word "add" in this line:
...and produces the following error code:
The method add(T, T) in the type Addition<T> is not applicable for the arguments (Object, Object)
I'm also confused by the syntax in the add method signature:
Are you casting a GenericMatrix<T> as type <T>?
Finally, I'm not clear how I would call this method. For generic matrices A and B, this command produces a slew of error messages:
(Inserting <Integer> into the command in different locations produced no reduction of error messages.)
Somehow I feel I'm well out of my water in trying to tackle this seemingly straightforward problem, or else my luck has brought me to one of the thornier issues of Java programming. It seems like there are a lot of subtleties here that I'm not grasping...