This question already has answers here:
Main method in a static inner class.?
(4 answers)
Closed 1 year ago.
How to execut main method, if it is present in static inner class?
Main method is present in static inner class and we need to execute that main method.
class A {
static class B {
public static void main(String[] args) {
System.out.println("Done");
}
}
}
Try something like this:
java A$B
Update according to comments:
In linux shell you should escape $. So the command became:
java 'A$B'
Its just like simple class. Run command java A$B
When inner class is compiled, it is prepended with outer class name
In this case you two class files. i.e . A.class and A$B.class
java command takes the classname as the argument and not the filename
So simple command java A$B will do the work
If you have anonymous classes then the classnames will be like OuterClass$1, OuterClass$1 and so on.
So if you modify your example as follows, now including anonymous and method local inner classes
import java.io.Serializable;
public class A {
static class B {
public static void main(String[] args) {
System.out.println("Done");
Serializable obj = new Serializable() {
};
Serializable obj1 = new Serializable() {
};
class MethodLocalClass {
}
}
}
}
Then the class files you will get are A.class, A$B.class, A$B$1.class, A$B$2.class for the anonymous classes and A$B$1MethodLocalClass.class.
Hope this example helps a bit :)
If your .java file have inner/nested classes, post compilation those are generated as TheClass$xxx.class files by the compiler.
See this:
Inner class definitions produce additional class files. These class
files have names combining the inner and outer class names, such as
MyClass$MyInnerClass.class.
So you should do: java A$B.
In Eclipse go to Run -> Run Configurations -> then select Java Application in the left column -> click the new configuration icon in the top left.
In my case it automatically picked up my inner class with a main method. This was just a simple example class and I wanted to test it without creating another test/client class.
Related
Given a fully qualified class name that can be loaded with Class.forName(), is there a way to transform the name into what would be the result of loading the class and invoking getSimpleName() without actually attempting to load the class?
I need this capability for reflection purposes.
I'm going to say that you can't do it simply based on the name.
You can try to split on . and $, but this example code demonstrates that it is not always obvious where the simple name begins:
class Ideone
{
private static class Bar {};
public static void main (String[] args) throws java.lang.Exception
{
class Foo$o {
class Bar$bar {}
};
class Foo$o$Bar {
class Bar$bar {}
};
class Foo$o$Bar$Bar$bar {}
print(Ideone.class);
print(Bar.class);
print(Foo$o.class);
print(Foo$o.Bar$bar.class);
print(Foo$o$Bar.Bar$bar.class);
print(Foo$o$Bar$Bar$bar.class);
}
private static void print(Class<?> clazz) {
System.out.printf("fqn=%s, sn=%s%n", clazz.getName(), clazz.getSimpleName());
}
}
Output:
fqn=Ideone, sn=Ideone
fqn=Ideone$Bar, sn=Bar
fqn=Ideone$1Foo$o, sn=Foo$o
fqn=Ideone$1Foo$o$Bar$bar, sn=Bar$bar
fqn=Ideone$1Foo$o$Bar$Bar$bar, sn=Bar$bar
fqn=Ideone$2Foo$o$Bar$Bar$bar, sn=Foo$o$Bar$Bar$bar
Ideone demo
i.e. if you were to say "the bit of the name after the final $ or .", you'd be wrong.
The only conclusive way to do this is to load the class, potentially without initializing it:
Class<?> clazz = Class.forName(className, false, someClassLoadeR);
As demonstrated by the answer of #AndyTurner you cannot derive the simple name from the qualified class string in all cases.
But if the constraint without actually attempting to load the class does not forbid to read the contents of the class file, you could do the following (for the edge cases):
Get a InputStream for the class file contents via Class.getResourceAsStream()
Parse the beginning of the class file and read the super class name from the constant pool.
(as commented by #shmosel) Implement the logic of Class.getSimpleName(). The super class name allows you to replace Class.getSimpleBinaryString() which relies on an already loaded class.
I'm working on a a java project. I'm using eclipse with java 1.7. I wish to pass a variable value (string) to another program stored in other folder
main Proj
/ \
folder1 folder2
/ \ \
prog1.java prog2.java prog3.java
I have a variable, say msg of string type in prog2.java.
(1) I need to pass its value from prog2.java to prog3.java (note in other folder).
(2) Also, i wish to know how to call prog3.java in prog2.java. I do not want to separately run prog3.java, but then I run prog2.java, the prog3.java can automatically run.
(3) Can I make msg a private variable in java?
Can someone help how to achieve these tasks.
You can access a public method or public field from a public class (both have to be public in this case) from whatever package you want as long as it is part of the same project. You do this with import. Here are a couple of example classes.
This is some random class with a main method. It is in the package "folder2".
package folder2;
public class prog2 {
public static void main(String[] args) {
System.out.println("Printing from package: folder2");
}
}
Another class in a different package, "folder1", and calling the above main method. Notice the import statement.
package folder1;
import folder2.prog2; //Syntax is packageName.className
public class prog1 {
public static void main(String[] args) {
prog2.main(args); // Calling main method from another package
}
}
The output when you compile prog1.main.
Printing from package: folder2
Hope this helps.
Constraints:
I have a maven source code generator that I wrote that is creating POJO classes
from some data files that have nested namespaces. I want each namespace to
be nested as an inner class. In some cases out of my control I end up
with inner classes that are the same simple name as the outermost
class.
All the classes must be public scope as this is for a type safe
wrapper over something like a properties file, but hierarchical..
I can't change the names otherwise I am changing the names meaning and the namespace
that is enclosing data.
Given than I have the following code:
public class A
{
public class B
{
public class A
{
}
}
}
Inner classes should append the name of the outer class to form a unique namespace such as A$B$A.class, I haven't found a valid reason for this not to compile.
Is there any trick to get this to compile?
No. From the JLS section on class declarations:
It is a compile-time error if a class has the same simple name as any of its enclosing classes or interfaces.
Note: I somehow managed to miss this on my first pass through looking for an explicit rule. Check the edit history if you want the tortuous way I got here.
You asked: Is there any trick to get this to compile?.
The answer is: Well, maybe....
Create a class like the following:
public class A
{
public class B
{
public class X
{
}
}
}
And a class where this class is going to be used
public class AUse
{
public static void main(String[] args)
{
A.B.X aba = new A().new B().new X();
System.out.println("Created "+aba+" of class "+aba.getClass());
}
}
Then, download the Apache Byte Code Engineering Library (BCEL), and create and run the following class:
import java.io.FileOutputStream;
import org.apache.bcel.Repository;
import org.apache.bcel.util.BCELifier;
public class CreateCreators
{
public static void main(String[] args) throws Exception
{
new BCELifier(
Repository.lookupClass("A"),
new FileOutputStream("ACreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B"),
new FileOutputStream("A$BCreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B$X"),
new FileOutputStream("A$B$XCreator.java")).start();
new BCELifier(
Repository.lookupClass("AUse"),
new FileOutputStream("AUseCreator.java")).start();
}
}
This uses the BCELifier class from the BCEL. This is a class that takes a .class file, and creates a .java file that can be compiled to a .class file, that, when it is executed, creates the .class file that it was originally fed with. (Side note: I love this library).
So the A$B$XCreator.java file that is created there contains the BCEL code that is necessary to create the A$B$X.class file. This consists of statements like the generation of the constant pool and the instructions:
...
_cg = new ClassGen("A$B$X", "java.lang.Object", "A.java",
ACC_PUBLIC | ACC_SUPER, new String[] { });
...
il.append(_factory.createFieldAccess("A$B$X", "this$1",
new ObjectType("A$B"), Constants.PUTFIELD));
Similarly, the AUseCreator.java contains the BCEL code that creates the AUse.class. For example, the instruction of the constructor invocation of `A$B$X':
...
il.append(_factory.createInvoke("A$B$X", "<init>", Type.VOID,
new Type[] { new ObjectType("A$B") }, Constants.INVOKESPECIAL));
Now you can simply replace the String occurrences of "A$B$X" with "A$B$A" in the A$B$XCreator.java and AUseCreator.java, and then compile and run these classes.
The result will be a A$B$A.class file, and a AUse.class file that uses the A$B$A.class. Executing the AUse will print
Created A$B$A#15f5897 of class class A$B$A
I'm not sure whether this is considered as a "trick", or whether it still can be called "compiling" at all, but there is a way, at least. The key point is here, of course, that the fact that it did not compile is solely due to a limitation of the language, but there is no reason why this should not be representable in form of class files, regardless of how they are created.
You can't get it to compile, but more importantly, why would you need to?
What's wrong with:
public class A
{
public class B
{
public class InnerA
{
}
}
}
This seems like a design problem that you need to fix. If you can't rename it, consider anonymous inner classes. Or take some of those classes outside. Or just don't even use them.
It's a bit of a hack, but this compiles at my machine:
class A
{
public class B
{
public class Α
{
}
}
}
Try it. Literally: copy-past this thing ;)
SPOILER:
The name of the inner class is a capital letter alpha of the Greek alphabet. It's a Unicode character.
Depending on what you're after, the following might work for you:
public class A {
class B extends C {
}
public static void main(String[] args) {
new A().new B().new A();
}
}
class C {
class A {
{
System.out.println(getClass());
}
}
}
This question already has an answer here:
Import custom Java class
(1 answer)
Closed 9 years ago.
I am a beginner at java, I used to code in C++ and there when using classes I used to define them in separate files and then include those classes in my main file.
I'm trying to learn threads for socket programming so I can open multiple server ports as threads and accept multiple clients. I know that in Java the file name should be the same as the class name (correct me if i am wrong). This is what I am trying to do:
main.java
include derived.java;
class main1
{
main1()
{
System.out.println("Constructor of main1 class.");
}
void main1_method()
{
System.out.println("method of main 1 class");
}
public static void main(String[] args)
{
main1 my = new main1();
Derived derivedThread = new Derived();
derivedThread.start();
}
}
derived.java
public class derived extends Thread
{
public void run()
{
System.out.println("starting a new thread");
}
}
How can I create a derived class object in main and include it in my main1.java file?
I think I do not fully understand how classes work in Java and what classpath has to be used with it. I have a deadline for my networking project and I am very behind so please help me!
Delete your files and try this, this is how it should look in Java:
Derived class: Derived.java
public class Derived extends Thread {
public void run() {
System.out.println("starting a new thread");
}
}
Main1 class: Main1.java
public class Main1 {
public Main1() {
System.out.println("Constructor of main1 class.");
}
void main1_method() {
System.out.println("method of main 1 class");
}
public static void main(String[] args) {
Main1 my = new Main1();
Derived derivedThread = new Derived();
derivedThread.start();
}
}
Note:
1) Class names are always capitalized, and you are right, the filename must be the same. In addition, the constructor and any calls to the constructor must be capitalized.
2) If you put classes in the same package, you don't need to import them. If you have multiple packages, you would import like so: import packageName.className;. No need for .java at the end, strictly the class name. You can also have nested packages, so you might see things like: import java.util.ArrayList;. This would be using ArrayList class, found in the util package, which is in the java package (built in). You shouldn't have to worry much about making nested packages on smaller projects, but that's the concept.
3) Notice I added the public modifier to Main1 and it's constructor. It is good practice to give a modifier to class names and methods, as well as class variables. See this SO Question for information about modifiers. For a beginner, you should mostly only be concerned with public and private.
I hope that helps, and good luck with your Java studies.
No need to use this include derived.java; .Use import if the derived class exist in different package.The class Derived is different while calling and declaring.
class main1 // Class name must start with Uppercase
{
public static void main(String[] args)
{
main1 my = new main1(); // Can be remove
Derived derivedThread = new Derived();
derivedThread.start();
}
}
public class derived extends Thread // Change derived to Derived
--------------------^
{
public void run()
{
System.out.println("starting a new thread");
}
}
I have remove constructor and one method which is not used.
Ok, this might be kiddies question in java. We can't define two public classes in one file. But, in one of the examples from the book SCJP study guide, this example was mentioned:
public abstract class A{
public abstract void show(String data);
}
public class B extends A{
public void show(String data){
System.out.println("The string data is "+data);
}
public static void main(String [] args){
B b = new B();
b.show("Some sample string data");
}
}
When I copy pasted this into netbeans immediately compile error was thrown, that public class A should me mentioned in separate file. Is that example from SCJP styudy guide really wrong? Also in some of the mock test I found many questions having such pattern but in none of the options was a compiler error was mentioned. Getting worried here
yes, 2 top level public classes are not allowed in one file
Well, if one is being so picky: you can have multiple classes defined with a public modifier in the same file, that is, using the static nested(inner) class.
like this:
File -> Test.java
public class Test {
public static class SomeNestedClass {
}
}
Yes you can have two classes in the same file. You can have them by removing the public access modifier from both the class name, like shown below,
abstract class A{
public abstract void show(String data);
}
class B extends A{
public void show(String data){
System.out.println("The string data is "+data);
}
public static void main(String [] args){
B b = new B();
b.show("Some sample string data");
}
}
you can make 2 public classes in one file , inside a class that contains them .
it's also recommended to add "static" for them , if you do not need any reference to the container class .
You can put two public classes in one file, for example in the file Circle.java:
public class Test {
public static void main(String args[]) {
double cir = Circle.findCircumference(7.5);
System.out.print("Circumference of circle=" + cir);
}
}
public class Circle {
public static double findCircumference(double radius) {
return 2 * Math.PI * radius;
}
}
If you then run javac Circle.java, you will get an error:
Circle.java:1: error: class Test is public, should be declared in a file named Test.java
public class Test {
^
1 error
But if you run it with java Circle.java, then it will work.
Why? Probably because the java command, since java 11 (see here), can run also single source-file programs.
Imagine you could place two public classes in one file, then think about the work of the compiler: it has to build a .class file from your .java file that represents exactly one class (otherwise the .class ending wouldn't make any sense).
The way the JAVA Compiler works it will simply create a .class file with the name of your file and will search for the class with the name of the file in your given file – so it depends on your file name which class will be correctly compiled and which will not.
Long story short: no, you can't put two public classes in one file because the compiler wouldn't be able to handle that correctly.
(Edit: it of course is possible to define new classes INSIDE the one public class that has the same name as your file.)