hello, I'm a beginner in Java and I use IntelliJ, and I'm looking to replace Class.forName() with something that uses more basic coding. My project structure is I created class Alpha, which contains only 1 variable (public static ArrayList<Beta>). Beta is another class I created, and it extends class Alpha. Beta contains many variables, the class type of one of them is something I created, let's call it Gamma. I also created a bunch of classes that extend Gamma, let's call one of them Delta. So Delta extends Gamma, which extends Beta, which extends Alpha. In the Alpha class, I have a public static method. Inside that method, I use scanner.next() to read a text file and save a letter to variable name, type String. Basically, that letter should refer to one of my Delta classes. So I used Class.forName(name) to fetch me the Delta class that has the same name as the letter (all my Delta classes have just 1 letter in the class name, each with different letter, so all my Delta subclasses are found under Gamma). Problem is this causes ClassNotFoundException. Can anyone please tell me how to fix it or what would be a simpler alternative to fetch a class with a String?
#How to get subclass from class name as String? (Class.forName not working)
33 messages · Page 1 of 1 (latest)
⌛ This post has been reserved for your question.
Hey @north helm! Please use
/closeor theClose Postbutton above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
Use a Map<String, Class<?>> as a lookup table
Initialize it statically or in a constructor
You have to use the fully qualified name, meaning including the package name
Then all you do is get the class for a string, or throw an error
like this? Gamma someVariable = Map<name,Gamma>;
Ok, I initialized the map, but I don't understand why all the elements got saved as a Delta class that isn't even on the map lol I believe the scanner works properly because I have the right number of elements (using my test file), but they all got saved as Z which I added to the ArrayList once before the while loop, so only the 1st element should be Z. The capital letters are the Delta classes. I have below in my Alpha class.
public static ArrayList<Beta> listBeta = new ArrayList<>();
public static Map<String,Gamma> map = new HashMap<>()
{
{
Gamma c = new C();
Gamma d = new D();
Gamma e = new E();
Gamma n = new N();
put("C",c);
put("D",d);
put("E",e);
put("N",n);
}
};
public static ArrayList<Boolean> method (String filename) {
ArrayList<Boolean> result = new ArrayList<>();
listBeta.add(new Z());
Scanner scanner = null;
try {
File file = new File(filename);
scanner = new Scanner(file);
while (scanner.hasNext()) {
String s = scanner.next();
Gamma type = map.get(s);
listBeta.add(new Beta(type));
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} finally {
scanner.close();
}
[... I checked the elements' class types before this part of the code...]
return result;
}
Please format your code to make it more readable.
For java, it should look like this:
````java
public void foo() {
}
````
I can't specify the package name, cause it needs to work on someone else's machine as well
The package should not change across devices
What should the line look like? I had something like this, where s is variable type String...
Class<? extends Gamma> type = Class.forName(s).asSubclass(Gamma.class);
Seems correct
but that gave me the ClassNotFoundException, and I need the class for my method to do what it needs to do
Show me the code
/run
package a;
public class X {
public static void main(String[] args) throws ClassNotFoundException {
String s = "a.Z";
Class<? extends Y> type = Class.forName(s).asSubclass(Y.class);
System.out.println(type);
}
}
class Y extends X {}
class Z extends Y {}
Here is your java(15.0.2) output @trim saffron
class a.Z
Simple example⬆️
how do you get the package line to appear at the top? on my screen, I see a ton of imports... sorry, I'm really beginner...
Package (if there is one) should be above the imports
/run
Update: Discord changed their client to prevent sending messages
that are preceeded by a slash (/)
To run code you can use "./run" or " /run" until further notice
Here are my supported languages:
awk, bash, basic, basic.net, befunge93, bqn, brachylog, brainfuck, c, c++, cjam, clojure, cobol, coffeescript, cow, crystal, csharp, csharp.net, d, dart, dash, dragon, elixir, emacs, emojicode, erlang, file, forte, forth, fortran, freebasic, fsharp.net, fsi, go, golfscript, groovy, haskell, husk, iverilog, japt, java, javascript, jelly, julia, kotlin, lisp, llvm_ir, lolcode, lua, matl, nasm, nasm64, nim, ocaml, octave, osabie, paradoc, pascal, perl, php, ponylang, powershell, prolog, pure, pyth, python, python2, racket, raku, retina, rockstar, rscript, ruby, rust, samarium, scala, smalltalk, sqlite3, swift, typescript, vlang, vyxal, yeethon, zig
You can run code like this:
./run <language>
command line parameters (optional) - 1 per line
```
your code
```
standard input (optional)
Provided by the Engineer Man Discord Server - visit:
• https://emkc.org/run to get it in your own server
• https://discord.gg/engineerman for more info
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Alpha {
public static ArrayList<Beta> listBeta = new ArrayList<>();
public static ArrayList<Boolean> method (String filename) {
ArrayList<Boolean> result = new ArrayList<>();
listBeta.add(new Z());
Scanner scanner = null;
try {
File file = new File(filename);
scanner = new Scanner(file);
while (scanner.hasNext()) {
String s = scanner.next();
Class<? extends Gamma> type = Class.forName(s).asSubclass(Gamma.class);
listBeta.add(new Beta(type));
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} finally {
scanner.close();
}
for (int i = 0; i < listBeta.size(); i++) {
System.out.println(Gamma.getName(listBeta.get(i)));
}
return result;
}
public class Beta extends Alpha {
protected Gamma type;
protected boolean b1;
protected boolean b2;
public Beta() {
this.b1 = false;
this.b2 = false;
}
public <T> Beta (T type) {
this.type = (Gamma) type;
this.b1 = false;
this.b2 = false;
}
}
public class Gamma extends Beta {
static String name;
public Gamma() {
this.b1 = false;
this.b2 = false;
}
public static String getName(Beta beta) {
return name;
}
}
public class Z extends Gamma {
public Z() {
this.name = "Zero";
this.b1 = false;
this.b2 = false;
}
}
public class C extends Gamma {
public C() {
this.name = "Cookie";
}
} ```
This message has been formatted automatically. You can disable this using /preferences.
the rest of the Delta classes are pretty much as empty as C
What is the output?
If it is ClassNotFoundException then the string coming in from the file is incorrect
At this moment, the method should return an empty ArrayList<Boolean> but it does print to the console the list of names for each of the elements. The test file that I use is just a raw text file, the content looks like this: C E N D E
If it does print then what is the issue?
Ok, I think I figured out a simpler way to do this, but now I have a different problem lol so I will close this and open new post. Thank you everyone!
If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.