Java local class .class file names - java

What will be the name of the .class file when local classes with same name are present in more than one instance method of same class? How can JVM differentiate these local classes?

Code:
public class Test {
public static void main(String[] args) {
}
public void method1() {
class class1 {
}
}
public void method2() {
class class1 {
}
}
}
Generated classes:
Test.class
Test$1class1.class
Test$2class1.class
So it's OuterClass$(number)InnerClass

With both local classes and anonymous classes the compiler adds a number to the generated name.
Compiling the below code produced classes Test.class, Test$1Local.class, Test$2Local.class and Test$1Another.class so the compiler (jdk1.6.0_24) always adds a number to the name (maybe to avoid conflicts with inner classes) and if there are two local classes with the same name then it increments the number to avoid conflicts.
public class Test {
public void foo() {
class Local {
}
}
public void bar() {
class Local {
}
}
public void baz() {
class Another {
}
}
}

Consider the following class:
public class test
{
private void meth1()
{
class abc{}
}
private void meth2()
{
class abc{}
}
}
It will generate the following class files:
test.class
test$1abc.class
test$2abc.class

The JVM uses the format org.package.OuterClass$InnerClass
Anonymous classes are assigned a unique number.
http://www.retrologic.com/innerclasses.doc7.html

The format of the output .class file's name is PublicOuterClass$InnerClass.class. If the inner class is an anonymous class, then it will be replaced with a number and sequentially numbered starting with 1.

Related

In what order do local and anonymous classes compile in java?

Assume that I have two local classes with the same names, but they're defined in different methods. In what order will they compile and what names are they going to have?
class ExampleClass {
public void test() {
NestedClass.nestedTest2();
NestedClass.nestedTest();
}
private static class NestedClass {
private static int a;
public static void nestedTest() {
class Test1 {
void method1() {}
}
}
public static void nestedTest2() {
class Test1 {
void method2() {}
}
}
}
}
Using javac command I get these compiled files
ExampleClass$NestedClass$1Test1
ExampleClass$NestedClass$2Test1
There are other files, I just don't really thing it's necessary to list them all.
The question is, how come the first file (ending with $1Test1, which is defined in nestedTest() method ) get compiled earlier than the other one (defined in method nestedTest2)? What does the order depend on? As you see I also tried to call test methods in ExampleClass to change the order, but I didn't believe it would help and it actually doesn't.

Program will give an error if method not marked public ( all classes are in the same file)

I am trying to create an Anonymous class during which I came across following problem. In the following code when I change display method access modifier to default it gives an error but when I change it to public it works fine. Could you explain it to me why this happens.AFAIK public and default are work in similar as long as all classes are in same package. Please correct me if I am wrong.
//from file : Skg.java
package sandeep2;
class Skg1
{
public void display()
{
System.out.println("sandeep here");
}
}
class Skg2 {
public void say()
{
System.out.println("Skg2");
}
Skg1 obj = new Skg1()
{
**public void display()** //wont work if this is not public ????????????
{
System.out.println("I am ANONymous");
}
};
}
public class Skg {
public static void main(String[] args)
{
Skg2 x = new Skg2();
x.obj.display();
}
}
Class Skg2 attempts to create an instance of an anonymous inner class as a subclass of class Skg1. That anonymous inner class overrides Skg1.display(), which is public. You cannot override a method to reduce its visibility. Java does not permit it, and it would violate the substitution principle if you could do it.

Why doesn't the class containing main have to be public?

I declared the following class
class A { //not public
public static void main(String args[]) {
System.out.println("done");
}
When I compile and run it, it runs fine and prints the output "done". Same behavior even when I declare it as being in a "package a;"
However, if JVM spec mandates that main method should be public since "it can't see main otherwise", shouldn't it apply to the class as well?
If the JVM "can't see" A.main() when it is not declared public, how is it able to see the class A itself.
Is there any explanation for this other than "because the specification says so"?
The JVM has access to every class in the application all the time because one of its responsibilities is enforcing visibility rules. Therefore, one can draw the conclusion that it can ignore visibility rules if need be (e.g. when the user starts the application, the JVM has to find the entry point, which is main()).
In other words, the JVM is not a class accessing this function, so visibility doesn't apply. It is basically the overseer, managing the application from execution to termination.
For reference, see Execution.
When you declare a class private, you're not making it "invisible", and the same goes for your methods. Declaring a method private simply means it's not callable from outside your class. A static public method of a private class is publicly callable.
The reason the JVM can see a non-public class is because it controls visibility, meaning it sees everything and decides what can see/call/access what.
The use of public on a class is different than on a method, but the concept is the same.
On a method, the public keyword means the method can be used outside the class. An example would be:
class A {
public static void do() {
// Do something
}
}
class B {
public static void main(String[] args) {
A.do(); // This works because do() is public and static
}
}
The same concept applies to classes, but in a different way.
Using public on a class means that it can be used outside the current .java file (it will have its own .class file).
Here's an example:
//C.java
class C {
static void do() {
// Do something
}
public static void run() {
A.do(); // Works because A.do() is public and static
B.do(); // Does not work because B is not a public class
}
}
//A.java
public class A {
public static void main(String[] args) {
B.do(); // Works because B is in the same file
do(); // Duh...
}
public static void do() {
// Do something
}
}
class B {
static void do() {
// Do something
}
}

Main method in a static inner class.?

I've learnt that the only public class in a Java file must also have the main method. However, below you can see the main method inside an inner class instead?
What is the rule with regard to the main method definition in a source file?
public class TestBed {
public TestBed() {
System.out.println("Test bed c'tor");
}
#SuppressWarnings("unused")
private static class Tester {
public static void main(String[] args) {
TestBed tb = new TestBed();
tb.f();
}
}
void f() {
System.out.println("TestBed::f()");
}
}
If you want to start a class with java (the Java launcher: java test.MyClass) then this class must have a main method with the well known signature.
You can have a main method with the same signature anywhere you want. But don't expect that the launcher will find it.
P.S. The name of the language is Java, not JAVA.
There is a minor detail:
You may do this:
package test;
public class Test {
/**
* #param args the command line arguments
*/
static public class A {
public static void main(String[] args) {
System.err.println("hi");
}
}
}
java test.Test$A
but this is non standard ...
Any class that can have a static method can have a public static void main(String[] args).
This includes:
top-level classes (whether public or not), e.g.
public class Foo {
public static void main(String[] args) {
System.out.println("Hello");
}
}
and inner static classes (whether public or not) (like your example).
It does not include:
anonymous classes
inner non-static classes
So both of these are illegal:
public class Foo {
private Object bar = new Object() {
public static void main(String[] args) {
System.out.println("Hello");
}
};
}
public class Foo {
private class Bar {
public static void main(String[] args) {
System.out.println("Hello");
}
};
}
Every Java application must have a main method. It’s the starting point for the execution of the code in the application. Its method signature is:
public static void main(String[] args)
A static inner class is a class that is defined inside of a different class's definition and marked as being static.
For example, if the outer class is named TestBed, then an inner class of TestBed, which is named Tester, would be compiled into TestBed$Tester.class. The separation of .class files means that you can keep the supplemental, nested code tightly coupled to the primary, outer class.
They are in the same source file, and the inner class is actually inside the outer class. All that and you don't have to pay any sort of deployment or run time cost.
By using static inner classes, you can add additional support functionality to your systems for capabilities such as testing, while incurring no penalties in normal, production deployment.
To execute the main() method of that TestBed.Tester class,
% java TestBed$Tester
This is interesting as the code will compile and run in Eclipse, but will just compile from using commmand line. When you run from eclipse it will find the static main method from within the inner class and run it.
But when running java TestBed from the command line you will get error - Exception in thread "main" java.lang.NoSuchMethodError: main which is a valid error as you have not defined your main method in main class.
Why would you want to define your main method in an inner class? Your main method should be defined in public class, this is not a rule but common practice.
In below code I've moved the main method into outer class which works both in Eclipse & command line :
public class TestBed {
public TestBed() {
System.out.println("Test bed c'tor");
}
#SuppressWarnings("unused")
private static class Tester {
}
public static void main(String[] args) {
TestBed tb = new TestBed();
tb.f();
}
void f() {
System.out.println("TestBed::f()");
}
}

Why is javac not complaining about more than one public class per file?

Here's my sample class, that compiles (and runs) with version 1.6.0_14 of Java:
import java.util.List;
import java.util.ArrayList;
public class Sample {
List<InnerSample> iSamples;
public Sample() {
iSamples = new ArrayList<InnerSample>();
iSamples.add(new InnerSample("foo"));
iSamples.add(new InnerSample("bar"));
}
public static void main(String[] args) {
System.out.println("Testing...");
Sample s = new Sample();
for (InnerSample i : s.iSamples) {
System.out.println(i.str);
}
}
public class InnerSample {
String str;
public InnerSample(String str) {
this.str = str;
}
}
}
I know that you're supposed to only have one public class per file in Java, but is this more of a convention than a rule?
You're not allowed to have more than one top-level class per file. InnerSample is an inner class.
This is an example of what is prohibited in a single file:
public class Sample {
}
public class Sample2 {
}
See JLS §7.6.
You cannot have more than one top level public class.
Nested/inner classes/interfaces/enums/#annotations don't count.
In your example, InnerSample is an "inner" class. An inner class MUST be inside another class (and thus, inside the outer class' source file).
Because it is an inner public class

Categories

Resources