I have a program called MyProgram.java. I want to run it from different directory which will be run on another machine. So I made a directory and copied MyProgram.class file and made a .bat file that runs it (Run.bat) which includes the command: #java MyProgram.
This didn't work, I had to copy SPVerification$1.class that was generated from Eclipse in order to make it work.
What is this XXX$1.class files and why do I need them beside the XXX.class file in order to run an application?
If your .java file have inner/nested classes , post compilation those are generated as Yourclass$xxx.class files by the java compiler.
Inner class definitions produce additional class files. These class
files have names combining the inner and outer class names, such as
MyClass$MyInnerClass.class. - Source
Example (edit)
Considering following Class definition
// MyClass class
public class MyClass{
// Inner class Test1
class Inner1 {
}
// Inner class Test2
class Inner2{
}
public static void main(String [] args) {
// Anonymous inner class 1
new Object() {
};
// Anonymous inner class 2
new Object() {
};
System.out.println("Bunch of $ files :)");
}
}
Will generate these following Files
MyClass.class
MyClass$Inner1.class
MyClass$Inner2.class
MyClass$1.class
MyClass$2.class
They are anonymous inner classes. In other words, when you have a piece like
class OuterClass {
// ...
void method() {
Thread t = new Thread(new Runnable() {
// ... code implementing Runnable interface ...
});
// ... code to use t or whatever
}
}
That generates anonymous inner class, in this case implementing the Runnable interface, and compiled code of that class goes to a OuterClass$<number>.class file. You can have more than one such class, with increasing number in the .class file name.
Note that syntax is exactly the same even if you extend a class with the anonymous inner class, instead of implementing an interface. This is a slightly different from creating named classes, where you need to use implements and extends as appropriate.
Related
I knew that when a class has an inner class then this class will be compiled to two class files. Today I have codes as below
public class GenericDeserializer {
public static void main(String[] args) {
String cityPageLoadJson = "{\"count\":2,\"pageLoad\":[{\"id\":4,\"name\":\"HAN\"},{\"id\":8,\"name\":\"SGN\"}]}";
Type type = new TypeToken<GenericResult<City>>() {
}.getType();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
GenericResult<City> cityPageLoad = gson.fromJson(cityPageLoadJson, type);
for (City city : cityPageLoad.getPageLoad()) {
System.out.println(gson.toJson(city));
}
}
}
Although the above one has no inner class, java compiler still creates two class files:
GenericDeserializer.class
GenericDeserializer$1.class
Using Java Decompiler tool, I see content of the second
package net.tuandn.training.lesson.gson;
import com.google.gson.reflect.TypeToken;
import net.tuandn.training.model.City;
import net.tuandn.training.model.GenericResult;
final class GenericDeserializer$1 extends TypeToken<GenericResult<City>>
{
}
Could anybody please explain why this class is created?
And when are multiple class files created on compiling?
Thank a lot!
Two class files are generated because you are using an anonymous class in the following statement:
TypeToken<GenericResult<City>>() {
.....
}
Each anonymous class file uses the same name as of the container class and appends a $1/$2 and so on.
new TypeToken<GenericResult<City>>() {
}
creates an anonymous inner class. Anonymous inner classes, just like inner classes are compiled to separate class files. Since anonymous class don't have name, that is why numbers are used to generate unique names for each such classes. The number you see there after $ is the numbering for that anonymous class, as they come in order in your enclosing class.
If you use more anonymous classes like that, the number will increment by 1. So for more anonymous classes, the generated class files would look like:
GenericDeserializer$1.class
GenericDeserializer$2.class
GenericDeserializer$3.class
GenericDeserializer$4.class
....
For inner classes however, the value after the $ is the name of the inner class, as you already would have noticed.
And when are multiple class files created on compiling?
Yes, those classes are generated, when you compile your top-level class.
Simple enough, your decompiled class shows
final class GenericDeserializer$1 extends TypeToken<GenericResult<City>>
So you have a TypeToken<GenericResult<City>> somewhere.
Looking through your code we see
Type type = new TypeToken<GenericResult<City>>() { /* anonymous inner class */ }.getType();
There's an anonymous inner class declaration there which will therefore get its own class file with $X suffix.
While compiling the code of Tic Tac Toe and also while running some codes in java using swing and awt packages. I'm getting a $ appended class file generation, parallel to the ClassName.class file. What may be the reason? Its Whether due to the usage of ActionListeners, it Happens. Usually these kind of creation of .bak file will be generated while doing C programs involving structures.
Support needed regarding these two scenarios.
Class files containing $ in their names are nothing but the inner classes or anonymous inner classes that you might have used inside your top-level class.
For e.g, If you have a class declaration like this: -
public class A {
public class B {
}
}
Then you will have two class files generated: - A.class and A$B.class.
This shows the containment of class B inside class A.
In case of ActionListener this is what is happening, in your code.
UPDATE: -
If you are using anonymous inner class, then also you will get class name with $ in it: -
interface A {
public void show();
}
public class Foo {
public static void main(String[] a) {
new A() {
#Override
public void show() {
System.out.println("Hello");
}
}.show();
}
}
Then the class files generated will be: - Foo.class and Foo$1.class.
So, if you are using ActionListener as anonymous inner class, then also you would get that $, in your class file name for that anonymous inner class.
Yep, the Java compiler would compile an inner-class Bar of the "main" Foo class as Foo$Bar...
That is:
class Foo {
class Bar {
}
}
would create Foo.class and Foo$Bar.class
Why do you ask? I mean, what's the actual problem?
Cheers. Keith.
is there a way to declare 2 classes on the same .java file using Eclipse - also how the compiler will distinguish the .class for each declare class.
example
public class ThisTest
{
public static void main(String[] args)
{
}
}
class SimpleArray
{
}
thank you for your time.
is there a way to declare 2 classes on the same .java file using Eclipse
Yes, you can have several classes defined in a single .java file, but there may at most one public class in each file. (Just as in your example.)
Note that if you have a public class in a .java file, the name of that class must be the same as the name of the .java file.
how the compiler will distinguish the .class for each declare class.
The names of the .class files does not depend on the name of the .java file, but on the identifiers of the class declarations.
If you have
class A {}
class B {}
in a file named Classes.java, you'll get A.class and B.class if you compile it.
Yes, exactly like your example.
The extra class need to be non-public
You could also define inner/nested classes. In this case you should investigate the difference
Java inner class and static nested class
public class ThisTest
{
public static void main(String[] args)
{
}
static class SimpleArray
{
}
class SimpleArray2 {}
}
class Buddy {}
Each class will be located in an own .class file in a directory similar to the package.
Nested classes get its host prefixed and separated by an '$'.
The above case results in four class files
ThisTest.class
ThisTest$SimpleArray.class
ThisTest$SimpleArray2.class
Buddy.class
Just check the bin or classes folder of your eclipse project.
When decompiling a specific jar using java decompiler (http://java.decompiler.free.fr/) I got some strange code I cannot identify what is. can someone help me? the code is something like:
Foo.access$004(Foo.this);
or this
Bar.access$006(Bar.this);
or else
Baz.access$102(Baz.this, true)
What are these methods access$004, access$006 and access$102?
Synthetic methods like this get created to support acessing private methods of inner classes. Since inner classes were not part of the initial jvm version, the access modifiers could not really handle this case. The solution was to create additional package-visible methods that delegate to the private implementation.
public class Example {
private static class Inner {
private void innerMethod() { ... }
}
public void test() {
Inner inner = ...
inner.innerMethod():
}
}
The compile would create a new method of the Inner class like this:
static void access$000(Inner inner) {
inner.innerMethod();
}
And replace the call in the test method like this:
Inner.access$000(inner);
The static access$000 is package visible and so accessible from the outer class, and being inside the same Inner class it can delegate to the private innerMethod.
These are auto-generated methods which are created by the compiler in some cases (for example when accessing private fields of another class directly, e.g., in case of nested classes).
See also What is the meaning of "static synthetic"? and Synthetic Class in Java.
If you get the relevant .class file (run jar through unzip), and run the .class file through JAD
JAD MyClass.class
then you may find that the output JAD file has decompiled that particular line in a more meaningful way, e.g.
Baz.access$102(Baz.this, true)
shows up in the JAD output as simply
myMemberVaiable = true
where myMemberVaiable is a member of class Baz that you will recognise.
I have a nested static class like:
package a.b
public class TopClass {
public static class InnerClass {
}
}
I want to instantiate with Class.forName() but it raises a ClassNotFoundException .
Class.forName("a.b.TopClass"); // Works fine.
Class.forName("a.b.TopClass.InnerClass"); // raises exception
TopClass.InnerClass instance = new TopClass.InnerClass(); // works fine
What is wrong in my code?
Udo.
Nested classes use "$" as the separator:
Class.forName("a.b.TopClass$InnerClass");
That way the JRE can use dots to determine packages, without worrying about nested classes. You'll spot this if you look at the generated class file, which will be TopClass$InnerClass.class.
(EDIT: Apologies for the original inaccuracy. Head was stuck in .NET land until I thought about the filenames...)
try
Class.forName("a.b.TopClass$InnerClass");
Inner classes are accessed via dollar sign:
Class.forName("a.b.TopClass");
Class.forName("a.b.TopClass$InnerClass");
Inner class is always accessed via dollar sign because when java compiler compile the java source code file it generates .class file(byte code).
if there is only one class for example Hello.java and this class is an outer class then java compiler on compilation generate Hello.class file but if this class has an inner class HelloInner then java compiler generates d Hello$HelloInner.class(byte code).
so bytecode always looks like for following snippet with name Outer.java:
public class Outer
{
public var;//member variable
Outer()//constructor
{
}
class Inner1
{
class Inner2
{
}
}
}
so byte code is:Outer$Inner1$Inner2.class
that's why we use $ sign to access inner class .:)