Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Using static method for generic class  RSS feed

 
Tom Gibbins
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi there,

I'm having some trouble using an object created from a generic class into a static method. My code is the following:

In main, the intArray (line 16) i create works just fine and can be added to the method. My problems are:

1. genIntArray (line 17 cannot be instantiated (why? Should it not work when you create an object integer in the constructor and cast it to E[]?).
2. In line 20, min method does not recognize the input. I get the message: "The method min(E[]) in the type minArray<E> is not applicable for the arguments (minArray<Integer>[])".

What am i doing wrong? Where does my logic fail? All these brackets are giving me a headache. (I realize the constructor already defines the array, so adding 5 should not be necessary?). Thank you for your time

 
Junilu Lacar
Sheriff
Posts: 11165
160
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your main() should be public static void.

To your main issue, it's illegal to create an array of generic type (which forces you to do that hack on line 5) and in the case of line 17, a parameterized type. See Item 25 in Bloch's chapter on Generics: https://www.infoq.com/resource/articles/bloch-effective-java-2e/en/resources/Bloch_Ch05.pdf

Apart from that, I don't really understand what you're trying to achieve with that code.
 
Stephan van Hulst
Saloon Keeper
Posts: 7817
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tom Gibbins wrote:1. genIntArray (line 17 cannot be instantiated (why? Should it not work when you create an object integer in the constructor and cast it to E[]?).

Arrays of generic types are forbidden. Generics and arrays don't play nice together, so you shouldn't combine them.

2. In line 20, min method does not recognize the input. I get the message: "The method min(E[]) in the type minArray<E> is not applicable for the arguments (minArray<Integer>[])".

Your method expects an array of some type that is comparable to itself. If genIntArray was a valid declaration, you still wouldn't be able to pass it to the min() method, because minArray doesn't implement Comparable<minArray>.

I realize the constructor already defines the array, so adding 5 should not be necessary?

Line 5 assigns a new array to your arr field. Without it, arr would be null. It's still bad though, because you're casting an Object[] to an E[], which undoubtedly will cause a ClassCastException when you try to access an array element if E is anything other than Object.

Don't use unchecked casts. Casting new Object[10] to E[] is wrong, and will cause problems. The compiler will actually warn you about this. Try to eliminate warnings.

"How do I instantiate an instance of E[] then?", you might ask. You don't. If you really wanted to use an array, it would have to be of type Object[]. However, there's rarely a good reason to use an array in favor of a Collection type.

Uses of a Comparable as a type bound should be contravariant: E extends Comparable<? super E>

Your class name starts with a lower case letter. Class names should start with a capital letter.

Your main method is not static.
 
Campbell Ritchie
Marshal
Posts: 55772
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:. . . there's rarely a good reason to use an array in favor of a Collection type. . . ..
Unless you are writing your own collection type, maybe. But that isn't a common occurrence.
 
Tom Gibbins
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the replies. I think maybe i did not formulate my question properly, let me try again. Say i have a generic class with a generic method:


What i would like to do is to create two arrays of, say, Integers and Double, and compare them in the min method. I realize there are much easier ways to do this, my purpose here is solely to grasp how java generics work (and doesn't work) when comparing generic classes.
Right now my main trouble is to create an array from the generic class that fits into the min method.

Thank you.
 
Stephan van Hulst
Saloon Keeper
Posts: 7817
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So then, why the arr field? Why the constructor? Just create an Integer[] and pass it to the min() method.
 
Tom Gibbins
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because i can't get that to work. I should perhaps mention that i'm using JUnit to test this code, not a main method (i just added that for simplicity). If i initialize an Integer array with some values in the JUnit test case file, and try to pass this into the method using an AssertEquals, i get the compiler message: The method min(Integer[]) is undefined for the type MinimumElementInArrayTests. I need to somehow make the compiler understand that i want this Integer array to be created and treated as the generic class E[], but i don't know how. I'll post the reelvant JUnit code i'm using below:


If i'm doing something unnecessary here, i welcome any advice.
 
Junilu Lacar
Sheriff
Posts: 11165
160
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That call to min(intArray) on line 13 is interpreted as an attempt to call MinimumElementInArrayTests.min(Integer[]), which you haven't defined, of course, because you intended to invoke the static min() method that is in another class. You can fix the error with a static import or by using the fully qualified name of the min() you want to call.
 
Tom Gibbins
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, but how do i create a generic class in the test file using the constructor from the production code that i can use with the method min? Let me be more explicit:


I completely understand why the standard intArray cannot be used in the test code. Integer class has no direct relationship with minArray, so how can it use its methods?. What i don't understand is why the same thing applies for the two other arrays. I instantiate them from the constructor (line 4-5 in first post)? So if i can instantiate them from the minArray class, why can i not use the method that also belongs to the minArray class?
 
Tom Gibbins
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My whole post boils down to this question: What kind of syntax would i have to write in the test code to be able to use the min method (line 20-22 in post above)?
 
Stephan van Hulst
Saloon Keeper
Posts: 7817
142
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For clarity in this post I'm going to refer to minArray as MinArray, because it more clearly reflects that it is a class name. You should change your code to do the same.

MinimumElementInArrayTests doesn't know where to find the min() method. Why should it be MinArray.min(), and not for example, Math.min()? It cannot determine that you want MinArray.min(), just because you pass it a MinArray as an  argument.

There are two ways you can tell your test class where to find the correct min() method. You can either qualify the method call with the class name:
or you can perform a static import:
Whatever you do, there is no point in creating an instance of MinArray, because it only contains the static method min(). Since it's a utility class, you can also drop its fields, constructors and the type parameter from the class declaration:
 
Tom Gibbins
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you very much, this is just what i needed.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!