I created a interface
named Fn
, but now I have NoClassDefFoundError
.
interface Fn {
void f();
}
class fn implements Fn {
void f() {println("default");}
}
void setup() {
fn_fn = new fn() {
public void f() {println("hello");}
};
func(_fn);
}
void func(Fnfn){
fn.f();
}
I changed the name of interface
to something else, but is Fn
like a reserved word?When I looked into it, it seems that there is no keyword Fn
in Processing or Java, but is this written incorrectly?Or is it a name that cannot be used?
Please let me know the details.
Probably developed in a Windows (or similar) environment, but
The name Fn
itself is not a problem, because there is a class (or interface) in the same package (directory) with the same name if it is not case sensitive: Fn
and fn
.
Therefore, Fn
and fN
, F
and f
will have the same symptom.
Examples include:
Main.java
public class Main {
public static void main(final String[]args) {
fn value = new fn();
value.f();
}
}
interface Fn {
void f();
}
class fn implements Fn {
@ Override
public void f(){
System.out.println("default");
}
}
Compiling it with javac Main.java
will generate the following files in the same directory:
- Fn.class
- Main.class
Then, when you run java-cp.Main
, you see the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: Fn(wrong name:fn)
at java.lang.ClassLoader.defineClass1 (Native Method)
at java.lang.ClassLoader.defineClass (Unknown Source)
at java.security.SecureClassLoader.defineClass (Unknown Source)
at java.net.URLClassLoader.defineClass (Unknown Source)
at java.net.URLClassLoader.access$100 (Unknown Source)
at java.net.URLClassLoader $1.run (Unknown Source)
at java.net.URLClassLoader $1.run (Unknown Source)
at java.security.AccessController.doPrivileged (Native Method)
at java.net.URLClassLoader.findClass (Unknown Source)
at java.lang.ClassLoader.loadClass (Unknown Source)
at sun.misc.Launcher $AppClassLoader.loadClass (Unknown Source)
at java.lang.ClassLoader.loadClass (Unknown Source)
at java.lang.ClassLoader.defineClass1 (Native Method)
at java.lang.ClassLoader.defineClass (Unknown Source)
at java.security.SecureClassLoader.defineClass (Unknown Source)
at java.net.URLClassLoader.defineClass (Unknown Source)
at java.net.URLClassLoader.access$100 (Unknown Source)
at java.net.URLClassLoader $1.run (Unknown Source)
at java.net.URLClassLoader $1.run (Unknown Source)
at java.security.AccessController.doPrivileged (Native Method)
at java.net.URLClassLoader.findClass (Unknown Source)
at java.lang.ClassLoader.loadClass (Unknown Source)
at sun.misc.Launcher $AppClassLoader.loadClass (Unknown Source)
at java.lang.ClassLoader.loadClass (Unknown Source)
at Main.main (Main.java:3)
This is because fn
is used in Main.java:3
, but the file fn.class
does not exist.
Because Windows cannot create the same filename in the same directory with only different uppercase and lowercase characters, fn.class
is not generated and NoClassDefFoundError
occurs.
Annex 1
This issue does not occur on Linux or similar environments.
(I haven't tried it yet, so I don't know if it will happen on Linux.)
>docker pull java:8
>docker run-it -- name java-sand-box-v D:\Main.java:/Main.java:8
root@45c1697cb501:/#javacMain.java
root@45c1697cb501:/#ls-lt | grep "\.class"
-rw -r --r --1 root root 389 May 2008:50 fn.class
-rw -r --r -- 1 root root 105 May 2008:50 Fn.class
-rw -r --r --1 root root 300 May 2008:50 Main.class
root@45c1697cb501:/#java-cp.Main
default
Side 2
There is a rule that Java Type starts with uppercase letters, so as long as you name and code according to the rules, this problem will not occur.
© 2024 OneMinuteCode. All rights reserved.