0

I'm extremely new to Java, after a few hours of looking around I finally found a way to create new instances of classes at runtime using Reflection. The issue being there is a certain amount of ambiguity in other answers and explanations of Reflection because people explain HOW to fix the problem and not WHY the fix works.

Currently the most broad reflection syntax I could find was:

Class clazz = Class.forName(fullClassPath);
Constructor<Color> ctor = clazz.getConstructor(String.class);
Object object = ctor.newInstance(new Object[] {name});

But there are minor problems, I am having issues primarily with comprehension. In all other explanations the answers are hand-tailored to the error given. In my case while attempting to use it I apparently misunderstood the way it works.

public void createInstance() {
    String name = name; 
    try {
        Class clazz = Class.forName(fullClassPath);
        Constructor<Color> ctor = clazz.getConstructor(String.class);
        Object object = ctor.newInstance(new Object[] {name});
    } catch (Exception e) {
        }
    }

In my mind the way this would work is it would pull the current class, use it's constructor, and then rename the instance (also changing the directory name... I hope). The issue being there are some holes in that interpretation that I don't think fully mesh...

I should mention that this DOES throw an error and resorts to the catch statement rather than running the code.

I would expect reflection to require an instance method to run it properly so it can change the path for any class it is part of... but then an instance must be created PRIOR to calling the method, which would (in my mind) be unwieldy, and therefore probably incorrect.

In a static method it would have to pull from a common database, which would simply never work.

Errors given are:

java.lang.ClassNotFoundException: saveload.Colornull
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
(Irrelevant context removed)

Update: I was able to find a way that should seem to work much better, by attempting to construct the class in a static method (and changing where certain variables are being pulled from) I was able to make it finally read an actual name, changing the errors from:

java.lang.ClassNotFoundException: saveload.Colornull
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
etc...

to:

java.lang.ClassNotFoundException: (Name from user input here)
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
etc...
  • 1
    Don't use reflection to create new class instances. – DwB Jul 26 '19 at 20:41
  • (1) What is the exception you get? (2) What do you mean by "rename the instance" and "change the path"? (3) Maybe [Trail: The Reflection API](https://docs.oracle.com/javase/tutorial/reflect/index.html) and [What is reflection and why is it useful?](https://stackoverflow.com/questions/37628/what-is-reflection-and-why-is-it-useful) can help you understand some concepts. – Slaw Jul 26 '19 at 20:49
  • @DwB Then would would you recommend? Until I found reflection all sources said it was impossible to create and name an instance at runtime. – Michael Crenshaw Jul 26 '19 at 20:59
  • Well, the error is telling you the class `saveload.Colornull` doesn't exist (the `null` part seems odd). But what are you actually trying to do? – Slaw Jul 26 '19 at 21:10
  • @Slaw, I deeply apologize for not adding the errors in the original post. That has been fixed, thank you for pointing it out. I will look through those sources, but also somewhat doubt it will have quite what I need. I appreciated the stack overflow link, but it wasn't quite what I need. I always appreciate knowing why things are useful... but in this case if I want to understand how to properly use reflection then I need to know _how_ it works. – Michael Crenshaw Jul 26 '19 at 21:10
  • I'm sorry if I was unclear, i'm still attempting to learn proper terminology and important context... The current goal is to create, and declare (or change the declaration of) a class based on user input. So the user could select add a new Color class for instance, and then "name" (declare) the class from the console. I'm essentially attempting to use dynamic class creation in a static language... hence the issues. – Michael Crenshaw Jul 26 '19 at 21:16
  • @Andreas I appreciate the advice. If reflection is such a bad idea then do you know of a way to create classes declared from user input, that doesn't use reflection? – Michael Crenshaw Jul 26 '19 at 21:53
  • 1
    What does "create classes declared from user input" really mean? You want a user to be able to create instances of **any** class in the entire Java Runtime Library? How would you even know how to pass in any required parameters? --- Or is it that you have a smaller list of custom classes you wrote, and that you know how to instantiate, and want to allow user to identify which one to create? If so, perhaps a `switch` statement would be a better solution for you. – Andreas Jul 26 '19 at 22:00
  • 1
    Are you trying to declare new classes at runtime? As in, create a class named `Foo` that did not exist before? If so, reflection is not what you need; reflection works with _existing_ classes. You can use, might even _need_ to use, reflection to instantiate such a class and invoke methods on the instance, but you need to create the class first. – Slaw Jul 26 '19 at 22:28
  • 'Static and instance classes' is meaningless. – user207421 Jul 27 '19 at 00:39
  • I'm very sorry for any confusion, allow me to be very clear here. I am attempting to create new instances of a class during runtime. If I have a class ```foo``` and I want to create an instance of it I would want to (in a dynamic language) type something like this: ```SomeClass (user input here) = new SomeClass;``` That isn't possible in Java to my knowledge. Reflection appears to be the only way to do that. So what I am attempting to do is create an instance of ```foo``` and then change the name. Basically I want to use reflection to change the name used to call said instance to user input. – Michael Crenshaw Jul 27 '19 at 14:45
  • This doesn't clarify much. Change the name of what? But anyway, this looks like a gigantic XY problem. You shouldn't use reflection in general. Java is not a dynamic language. Reflection is a useful tool for very generic, low-level, advanced framework code. You should tell what concrete problem you're trying to solve, and we could advise the proper way to solve it, which most probably is not reflection. – JB Nizet Jul 27 '19 at 14:48
  • Reflection cannot change the name of fields or parameters; local variables are not even accessible through reflection. If you want to reflectively instantiate an object and associate the instance with a name defined by the user, use a `Map`. However, as JB said, this may be an [XY Problem](https://en.wikipedia.org/wiki/XY_problem). – Slaw Jul 28 '19 at 00:29
  • While this is an XY Problem, I didn't mind if reflection solved my problem. I wanted to understand it better before moving on to another possible solution (like maps, which I had tried before). I was hoping for some understanding of why what I was doing wouldn't work (because I was using code provided by a different answer it had to be where and when I was using it) rather than being told reflection was above my pay grade. I appreciate all the concern but I doubt this post will accomplish anything. Thanks for all the input despite not fixing the problem I learned a decent bit from this post – Michael Crenshaw Jul 30 '19 at 14:42

0 Answers0