ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm having a problem with a Java generic class in which I'm trying to create an array of objects containing the generic type:
Code:
import java.lang.reflect.Array;
class TestClass <T extends Comparable <T> >
{
public static void main(String[] args)
{ TestClass testTestClass = new TestClass(16); }
TestClass(int max)
//{ testArray = (TestNode[]) new Object[max]; }
{ testArray = (TestNode[]) Array.newInstance(TestNode.class, max); }
private class TestNode extends Object
{
TestNode(T copy)
{ value = copy; }
public T value;
};
private TestNode[] testArray;
};
The problem is with initialization of testArray. I receive the run-time exception:
Code:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LTestClass$TestNode;
at TestClass.<init>(TestClass.java:7)
at TestClass.main(TestClass.java:4)
This obviously means that it doesn't like my new strategy, but it won't compile if I try to create an array of TestNode. I'm a C/C++ guy but I'm being forced to use Java, so I'm learning the hard way that having a C++ mind isn't easy in Java. Thanks.
ta0kira
Yeah, that's it. Arrays do not forget their type so it will always be an array of type Object, which will produce a ClassCastException if you try to cast to anything else. Generics tend to be a real mess; one of the best references is the PDF here: http://www.angelikalanger.com/Generi...nericsFAQ.html
By the way, you don't need to specify that TestNode extends Object - all classes do so by default. And the semi-colon after class defintions, that definitely shows you're a C++ guy. It is OK, it just does not add anything and it may even be confusing considering that a semi-colon is used in declaring anonymous inner classes.
Thanks! Surprisingly, it isn't the ironic love story where one is forced to live with the much despised and judged Java and eventually comes to endear it's beauty as a programming language. In fact it seems to be the opposite because I can't seem to do anything that makes sense to me, which would make it a lot more efficient! I miss my references to pointers and pointers to pointers in C++...
ta0kira
PS That link is actually where I found the answer!
Thanks! Surprisingly, it isn't the ironic love story where one is forced to live with the much despised and judged Java and eventually comes to endear it's beauty as a programming language. In fact it seems to be the opposite because I can't seem to do anything that makes sense to me, which would make it a lot more efficient! I miss my references to pointers and pointers to pointers in C++...
ta0kira
Regarding "I miss my references to pointers and pointers to pointers in C++" - it's not a problem with Java.
The problem that pisses me off is Java does not have normal in my understanding scoping rules like C/C++/Perl/Pascal have.
I.e. you can't without an anonymous class write something like
Code:
{
int i = 1;
int j = 2;
int k = 3;
{
int i = i + 3; // a new 'i' has been introduced in this scope,
// it inherited its value from the outer 'i' and was
// incremented ny 3, so now the new 'i' is 4.
}
}
For the same reason I don't like Python.
Last edited by Sergei Steshenko; 10-31-2008 at 01:51 AM.
Regarding "I miss my references to pointers and pointers to pointers in C++" - it's not a problem with Java.
Really? I sure would like to know how to get around it. I'm talking about things like passing a std::string& recursively and having each call add to it so that I can spare copying the string every time, plus use my return for something else like bool. Or having a caller pass a reference to a pointer so the function can replace the pointer that the caller is using. I can work around it with a wrapper class (basically empty other than an object,) but that's pretty ugly and confusing to non-C++ers.
ta0kira
Really? I sure would like to know how to get around it. I'm talking about things like passing a std::string& recursively and having each call add to it so that I can spare copying the string every time, plus use my return for something else like bool. Or having a caller pass a reference to a pointer so the function can replace the pointer that the caller is using. I can work around it with a wrapper class (basically empty other than an object,) but that's pretty ugly and confusing to non-C++ers.
ta0kira
I am not a Java guy, but AFAIK, objects (not primitive types like int) are passed in Java by reference anyway.
Sorry, bad example. The thing with strings is there's no append function so you have to make a new one, making it impossible to modify it as an argument without a wrapper or returning a new string.
One possible dereference layer is a joke. You can't do things like pass a NULL pointer and have it come back pointing to something else, and you can't store a reference to a pointer so that when that pointer changes so does the reference. E.g. "I always want to know what's contained in variable X (not just the object's contents) even if a new object is inserted into it."
ta0kira
Sorry, bad example. The thing with strings is there's no append function so you have to make a new one, making it impossible to modify it without a wrapper or returning a new string.
One possible dereference layer is a joke. You can't do things like pass a NULL pointer and have it come back pointing to something else, and you can't store a reference to a pointer so that when that pointer changes so does the reference. E.g. "I always want to know what's contained in variable X (not just the object's contents) even if a new object is inserted into it."
ta0kira
Then, why do you write in Java in the first place ? School ?
Anyway, regarding "returning a new string" - that's the way things are in Java - eat memory and let garbage collector take care.
Old copy of the string will be collected - sooner or later, for better or for worse.
Sorry, bad example. The thing with strings is there's no append function so you have to make a new one, making it impossible to modify it as an argument without a wrapper or returning a new string.
That's why java has StringBuilder and StringBuffer classes. They do exactly what you need: they take a string, append to it and return the modified string after calling their toString() method.
Quote:
You can't do things like pass a NULL pointer and have it come back pointing to something else, and you can't store a reference to a pointer so that when that pointer changes so does the reference.
Try Bruce Eckel's Java book, it's written with C ++ in mind and shows exactly how the two languages are different; I get the impression that you are making things more difficult than they need to be because you approaching things too much in terms of C++ solutions. Many of the things you mention can be done - only, they are done differently.
I'm having a problem with a Java generic class in which I'm trying to create an array of objects containing the generic type:
Code:
import java.lang.reflect.Array;
class TestClass <T extends Comparable <T> >
{
public static void main(String[] args)
{ TestClass testTestClass = new TestClass(16); }
TestClass(int max)
//{ testArray = (TestNode[]) new Object[max]; }
{ testArray = (TestNode[]) Array.newInstance(TestNode.class, max); }
private class TestNode extends Object
{
TestNode(T copy)
{ value = copy; }
public T value;
};
private TestNode[] testArray;
};
The problem is with initialization of testArray. I receive the run-time exception:
Code:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LTestClass$TestNode;
at TestClass.<init>(TestClass.java:7)
at TestClass.main(TestClass.java:4)
This obviously means that it doesn't like my new strategy, but it won't compile if I try to create an array of TestNode. I'm a C/C++ guy but I'm being forced to use Java, so I'm learning the hard way that having a C++ mind isn't easy in Java. Thanks.
ta0kira
edit: Fixed; see red!
This is a simple problem with a simple solution. You don't need to use Array.newInstance. The problem is that TestNode is a generic class, because it is the nonstatic inner class of a generic class, so it is also generic. Just saying "TestNode" by itself inside the scope of TestClass means "TestClass<T>.TestNode". The reason why you couldn't say "new TestNode[max]" is the same reason as why you can't say "new ArrayList<String>[max]". i.e. the component type of the array must be a raw type; "TestNode" i.e. "TestClass<T>.TestNode" is not a raw type. The raw type is "TestClass.TestNode" -- you must qualify the "TestClass." part explicitly:
Code:
testArray = (TestNode[]) new TestClass.TestNode[max];
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.