We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi there.
As many before have no doubt tried, I'm attempting to create a class instance from a string. I've read that it's possible, and even seems fairly straightforward, but it's not working for me. Any help appreciated! Here's the code:
import java.lang.Class;
String model = "Ribbon";
void setup(){
noLoop();
// test 1 -- successfully prints the instance of a Ribbon class
Object ribbon1 = new Ribbon();
println(ribbon1.getClass());
// test 2 -- uncommenting the following line gives a ClassNotFoundException
//Object ribbon2 = Class.forName(model);
}
class Ribbon {
Ribbon(){
println("New Instance of Ribbon!");
}
}
Answers
java.lang
automatically.That
import
statement is completely unnecessary!https://Docs.Oracle.com/javase/9/docs/api/java/lang/Class.html#forName-java.lang.String-
Demands to be inside a
try {} / catch () {}
structure:https://Processing.org/reference/try.html
B/c it may throw a ClassNotFoundException:
https://Docs.Oracle.com/javase/9/docs/api/java/lang/ClassNotFoundException.html
However, b/c your target class Ribbon is also a nested inner class, all of its enclosing classes must be included in its fully qualified name too!
Take a look at the sketch example from this old forum thread link below:
https://Forum.Processing.org/two/discussion/7036/multiple-screens#Item_9
Once again I thank GoToLoop for the quick reply!
1) Didn't know that.
2) Didn't know that it was mandatory.
3) Ok, so now I've learned that Ribbon is a nested inner class of Sketch, I assume. The example was helpful, but I don't understand how, given my lone string variable, I can pass it as an arg to Class.forName() as a fully qualified name.
So, to be blunt, what does the line look like?
Wow, I can't wrap my head around that, I'm not there yet. 8-}
Ok, since you were so immensely helpful to me last time, let me tell you what my goal is in case you have a simpler solution.
A csv file has a field name that contains a string of a class I want to instantiate (along with its parms). I can parse it in a giant switch block to instantiate the right class, but after reading about Java's reflexive capabilities I thought it might be possible to do it that way. Well, perhaps it might be, but the hoops to jump through seem too onerous to negotiate...
In Java, the official & preferable way to instantiate classes & interfaces is via the operator
new
:https://Processing.org/reference/new.html
In Java, all of its members should be known at compile-time.
Reflective operations is an advanced & complicated way to inquire whether some member exists at runtime.
W/o knowing your ".csv" file, the classes you made to represent them, how similar those classes are to each other, there's no way to tailor the most possible simplest solution. :-@
But the try block still needs to cast inner as (Inner). If I have many inner classes, wouldn't each inner class need its own try block to properly cast the assignment? That rather defeats the point of a generalized solution. (I've gotten too accustomed to a simple eval() to do such things. I must jettison the idea that I can use such handy tricks in Java, it appears.)
It seems that a switch block is probably the simplest and most versatile solution. Oh well...
Thank you for your responses, as always.
The try/catch blocks are always mandatory in order to call newInstance(), no matter whether it's a regular, nested or inner class! =;
You can of course place the whole try/catch blocks inside some function which accepts a Class argument. *-:)
Then you can
(cast)
the returning Object to its actual datatype. :-bdBut reflective operations should be used as a last recourse only, when the regular means aren't enough! L-)
https://Forum.Processing.org/two/discussion/7147/some-simple-pulse-equations-using-trig-#Item_8
Cool! Thx!
Think I found the answer I'm looking for...
Proof of concept test, in case anyone else encounters the same problem:
The answer I originally sought can be found here.