I have a question that why main method is marked as public?
According to an answer on stackoverflow, It is declared as static
"The method is static because otherwise there would be ambiguity: which constructor should be called?"
But, can anyone can explain why it is declared public always?
Because the JLS, Section 12.1.4, says so:
The method main must be declared public, static, and void. It must specify a formal parameter (§8.4.1) whose declared type is array of String.
If it's not public, then it won't be found; you'll get
Error: Main method not found in class Main, please define the main method as:
public static void main(String[] args)
I believe, the rational behind enforcing main as public is more to do with the language specification – rather than whether something could be achieved or not.
Refer:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.1.4
The method main must be declared public, static, and void. It must
specify a formal parameter (§8.4.1) whose declared type is array of
String. Therefore, either of the following declarations is acceptable:
Java uses JNI launch java application will never have any issue in calling a private main – but this is more like jail-brake (like another jail-brake, where reflection API let you access private method) and definitely not in spirit of java specification.
If I remember till JDK 1.3 – it was not mandatory from developer’s perspective. i.e. even a private main was being accepted by JRE. Though, it was not inline with JLS 1.3.
I tried searching JLS 1.3 for a reference, but could not get a link. But I found that it was reported as a bug by developers across world:
Please refer: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4155575
So, a fix was made in subsequent version to enforce rule stated by JLS.
Now, the point is why JLS writer enforced this rule at first place – I really have no idea. The only thing I can think of is that – to keep it “obvious” and non-confusing for developers.
The initialization software that starts your program must be able to see main so that it can call it.
Because that is what is known as the "entry point" and if it is private, your program will not be able to run.
Public - main method is called by JVM to run the method which is outside the scope of project therefore the access specifier has to be public to permit call from anywhere outside the application.
From coderanch
When the code is executed, a JVM will be created and that will act as a container for the code we are trying to execute. Declaring this method as public allows the JVM to start the code execution. If method is private, JVM wont be able to call it.
There are ways to call a private method as well (eg by using Reflection), but that is not a standard way to do things.
In Java a function or variable in class in unaccessible untill an Object is created from the class, but the 'main' function is supposed to run at startup(without Object initiation) by JVM. So the 'main' is declared public as well as static so that it can be accessed outside class & without even an Object is created.
Yes the standards say so that main method should be public in Java. But it's not only for Java. However even for C#, main must be public.
So just think about it in real world scenarios.
E.g. you want to enter your room, but you should enter your home main door first (given room is inside the house...and no other means to enter the house)
Main door is the only publicly available access point.
Because the main method should be accessed by JVM without any restrictions from any where. I think you can find more info here: Why main method is public
Related
This question already has answers here:
out in System.out.println()
(8 answers)
Closed 1 year ago.
Firstly sorry if this a very basic question but someone ask me this and i don't have any answer.
In the statement
System.out.println()
System is a class in java.lang package, out is a static variable of System class and println() is an overloaded method.
Then Why System class doesn’t requires instantiation?
Thanks
java.lang.* is imported by default, i.e. all classes in the java.lang.* package are accessible by your program. So, your class has access to the members of the System class, among which is out, a static field of type PrintStream. Static members are not tied to an instance of the class, and so they can be accessed directly without instantiation. Hence, you are able to call the overloaded print methods available to out.
If you declare a static method in a Java class you don't need to create an object but simply invoke the method like System.out.println().
The System class cannot be instantiated anyway (cf. Javadoc).
This is achieved by setting the constructor to private:
private System() {
}
However, the System class in openj9 for example is partially filled by call of the afterClinitInitialization() method, which is called after thread initialization.
In there, the out Variable is actually initialized:
setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true));
See:
System.afterClinitInitialization()
Thread.initialize()
After that it stops being traceable via Github, but I guess you get the point. The initialization is just done by the JVM and due to out being static, no instance of System is needed to access the variable.
The topic of static variables however is well covered:
What does the 'static' keyword do in a class?
Static (Keyword) - Wikipedia.com
And to fully understand that, you must have a decent knowledge of the JVM and native programming, where I have to surrender myself.
I'm sure you all know the behaviour I mean - code such as:
Thread thread = new Thread();
int activeCount = thread.activeCount();
provokes a compiler warning. Why isn't it an error?
EDIT:
To be clear: question has nothing to do with Threads. I realise Thread examples are often given when discussing this because of the potential to really mess things up with them. But really the problem is that such usage is always nonsense and you can't (competently) write such a call and mean it. Any example of this type of method call would be barmy. Here's another:
String hello = "hello";
String number123AsString = hello.valueOf(123);
Which makes it look as if each String instance comes with a "String valueOf(int i)" method.
Basically I believe the Java designers made a mistake when they designed the language, and it's too late to fix it due to the compatibility issues involved. Yes, it can lead to very misleading code. Yes, you should avoid it. Yes, you should make sure your IDE is configured to treat it as an error, IMO. Should you ever design a language yourself, bear it in mind as an example of the kind of thing to avoid :)
Just to respond to DJClayworth's point, here's what's allowed in C#:
public class Foo
{
public static void Bar()
{
}
}
public class Abc
{
public void Test()
{
// Static methods in the same class and base classes
// (and outer classes) are available, with no
// qualification
Def();
// Static methods in other classes are available via
// the class name
Foo.Bar();
Abc abc = new Abc();
// This would *not* be legal. It being legal has no benefit,
// and just allows misleading code
// abc.Def();
}
public static void Def()
{
}
}
Why do I think it's misleading? Because if I look at code someVariable.SomeMethod() I expect it to use the value of someVariable. If SomeMethod() is a static method, that expectation is invalid; the code is tricking me. How can that possibly be a good thing?
Bizarrely enough, Java won't let you use a potentially uninitialized variable to call a static method, despite the fact that the only information it's going to use is the declared type of the variable. It's an inconsistent and unhelpful mess. Why allow it?
EDIT: This edit is a response to Clayton's answer, which claims it allows inheritance for static methods. It doesn't. Static methods just aren't polymorphic. Here's a short but complete program to demonstrate that:
class Base
{
static void foo()
{
System.out.println("Base.foo()");
}
}
class Derived extends Base
{
static void foo()
{
System.out.println("Derived.foo()");
}
}
public class Test
{
public static void main(String[] args)
{
Base b = new Derived();
b.foo(); // Prints "Base.foo()"
b = null;
b.foo(); // Still prints "Base.foo()"
}
}
As you can see, the execution-time value of b is completely ignored.
Why should it be an error? The instance has access to all the static methods. The static methods can't change the state of the instance (trying to is a compile error).
The problem with the well-known example that you give is very specific to threads, not static method calls. It looks as though you're getting the activeCount() for the thread referred to by thread, but you're really getting the count for the calling thread. This is a logical error that you as a programmer are making. Issuing a warning is the appropriate thing for the compiler to do in this case. It's up to you to heed the warning and fix your code.
EDIT: I realize that the syntax of the language is what's allowing you to write misleading code, but remember that the compiler and its warnings are part of the language too. The language allows you to do something that the compiler considers dubious, but it gives you the warning to make sure you're aware that it could cause problems.
They cannot make it an error anymore, because of all the code that is already out there.
I am with you on that it should be an error.
Maybe there should be an option/profile for the compiler to upgrade some warnings to errors.
Update: When they introduced the assert keyword in 1.4, which has similar potential compatibility issues with old code, they made it available only if you explicitly set the source mode to "1.4". I suppose one could make a it an error in a new source mode "java 7". But I doubt they would do it, considering that all the hassle it would cause. As others have pointed out, it is not strictly necessary to prevent you from writing confusing code. And language changes to Java should be limited to the strictly necessary at this point.
Short answer - the language allows it, so its not an error.
The really important thing, from the compiler's perspective, is that it be able to resolve symbols. In the case of a static method, it needs to know what class to look in for it -- since it's not associated with any particular object. Java's designers obviously decided that since they could determine the class of an object, they could also resolve the class of any static method for that object from any instance of the object. They choose to allow this -- swayed, perhaps, by #TofuBeer's observation -- to give the programmer some convenience. Other language designers have made different choices. I probably would have fallen into the latter camp, but it's not that big of a deal to me. I probably would allow the usage that #TofuBeer mentions, but having allowed it my position on not allowing access from an instance variable is less tenable.
Likely for the same logical that makes this not an error:
public class X
{
public static void foo()
{
}
public void bar()
{
foo(); // no need to do X.foo();
}
}
It isn't an error because it's part of the spec, but you're obviously asking about the rationale, which we can all guess at.
My guess is that the source of this is actually to allow a method in a class to invoke a static method in the same class without the hassle. Since calling x() is legal (even without the self class name), calling this.x() should be legal as well, and therefore calling via any object was made legal as well.
This also helps encourage users to turn private functions into static if they don't change the state.
Besides, compilers generally try to avoid declaring errors when there is no way that this could lead to a direct error. Since a static method does not change the state or care about the invoking object, it does not cause an actual error (just confusion) to allow this. A warning suffices.
The purpose of the instance variable reference is only to supply the type which encloses the static. If you look at the byte code invoking a static via instance.staticMethod or EnclosingClass.staticMethod produces the same invoke static method bytecode. No reference to the instance appears.
The answer as too why it's in there, well it just is. As long as you use the class. and not via an instance you will help avoid confusion in the future.
Probably you can change it in your IDE (in Eclipse Preferences -> Java -> Compiler -> Errors/Warnings)
There's not option for it. In java (like many other lang.) you can have access to all static members of a class through its class name or instance object of that class. That would be up to you and your case and software solution which one you should use that gives you more readability.
It's pretty old topic but still up-to-date and surprisingly bringing higher impact nowadays. As Jon mentioned, it might be just a mistake Java's designers made at the very beginning. But I wouldn't imagine before it can have impact on security.
Many coders know Apache Velocity, flexible and powerful template engine. It's so powerful that it allows to feed template with a set of named objects - stricly considered as objects from programming language (Java originally). Those objects can be accessed from within template like in programming language so for example Java's String instance can be used with all its public fields, properties and methods
$input.isEmpty()
where input is a String, runs directly through JVM and returns true or false to Velocity parser's output). So far so good.
But in Java all objects inherit from Object so our end-users can also put this to the template
$input.getClass()
to get an instance of String Class.
And with this reference they can also call a static method forName(String) on this
$input.getClass().forName("java.io.FileDescriptor")
use any class name and use it to whatever web server's account can do (deface, steal DB content, inspect config files, ...)
This exploit is somehow (in specific context) described here: https://github.com/veracode-research/solr-injection#7-cve-2019-17558-rce-via-velocity-template-by-_s00py
It wouldn't be possible if calling static methods from reference to the instance of class was prohibited.
I'm not saying that a particular programming framework is better than the other one or so but I just want to put a comparison. There's a port of Apache Velocity for .NET. In C# it's not possible to call static methods just from instance's reference what makes exploit like this useless:
$input.GetType().GetType("System.IO.FileStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
I just consider this:
instanceVar.staticMethod();
to be shorthand for this:
instanceVar.getClass().staticMethod();
If you always had to do this:
SomeClass.staticMethod();
then you wouldn't be able to leverage inheritance for static methods.
That is, by calling the static method via the instance you don't need to know what concrete class the instance is at compile time, only that it implements staticMethod() somewhere along the inheritance chain.
EDIT: This answer is wrong. See comments for details.
I'm writing an explanation for some code for a course, and have been accidentally using the words method and function interchangeably. I decided to go back over and fix the wording, but ran into a hole in my understanding.
From what I understand, a subroutine is a function if it doesn't act on an instance of a class (its effect is restricted to its explicit input/output), and is a method if it operates on an instance of a class (it may carry out side effects on the instance that make it impure).
There's a good discussion here on the topic. Note that by the accepted answer's definitions, a static method should actually be a function because an instance is never implicitly passed, and it doesn't have access to any instance's members.
With this is mind though, shouldn't static methods actually be functions?
By their definition they don't act on particular instances of a class; they're only "tied" to the class because of relation. I've seen a few good looking sites that refer to static subroutines as "methods" though (Oracle, Fredosaurus, ProgrammingSimplified), so either they're all overlooking the terminology, or I'm missing something (my guess is the latter).
I'd like to make sure I am using the correct wording.
Can anybody clear this up?
This quote from 8.4.3.2 may help:
A method that is declared static is called a class method.
A method that is not declared static is called an instance method [...].
Class methods: associated with a class.
Instance methods: associated with an instance.
Java just wants you to "think object-oriented". Also, static methods have access to a surrounding scope which may include state. In a way, the class is like an object itself.
The simple answer is that when Java decided to call everything a "method", they didn't care about the distinction between a function and a method in theoretical computer science.
Static methods are not exactly functions, the difference is subtle, but important.
A static method using only given input parameters is essentially a function.
But static methods may access static variables and other static functions (also using static variables) so static methods may have a state which is fundamentally different to a function which are by definition stateless.
(ADDENDUM: While programmers are often not so strict with using "function" as definition, a strict function in computer science can access only input parameters). So defining this case of accessing static fields it is not valid to say that static methods are always functions.
Another difference which justifies the usage of "static method" is that you can define in C derivates global functions and global variables which can be accessed everywhere. If you cannot access the class which contain static methods, the methods are inaccessible, too. So "static methods" are limited in their scope by design in contrast to global functions.
In Java, a user-defined class is actually an instance of a subclass of java.lang.Class.
In this sense, static methods are attached to an instance of a conceptual class: they are attached to an instance of a subclass of java.lang.Class.
With this in mind, the term "class method" (an alternate name for Java's static methods) begins to make sense. And the term "class method" can be found in many places: Objective C, Smalltalk, and the JLS -- to name just a few.
In computer science function clearly maps to a static method. But "method" of a class is a bit generic, like "member" (field member, method member). There are wordings like
Data members and method members have two separate name spaces: .x and .x() can coexist.
So the reason is, that as the philosoph Ludwig Wittgenstein said, Language is a tool with different contexts. "Method" is a nice moniker in the citation above to categorize a "member".
Your thinking is right and it makes sense. It's just not established terminology in the Java community. Let me explain some internals that can help understand why the terminology subsists.
Java is a class based object oriented language. A method is always member of a class or instance (This is a general statement valid for other programming languages too). We think of class and instance being both objects.
Instance method (dynamic)
You cannot invoke this method from a class directly, you have to create an instance. Each instance references that method. You can overwrite a method definition with the exact same method signature (when subclassing), i.e. the reference points to a different method (which has the same signature, but can have a different method body). The method is dynamic.
Class method (static)
You only can invoke this method from the class directly, i.e. you don't need to create an instance of that class. There is only one global definition of that method in the whole program. You cannot overwrite the exact same method signature when the method is declared static, because there is only one definition valid for the whole program. Note that the method is member of the class object itself, the instances have all the same unique (and fix) reference to that method.
Here is another take on the terminology, using Scala as a mnemonic:
In Scala you have objects, which are singleton instances of an implicitly defined class 1.
Per your definition, we can call these subroutines belonging to the object methods, as they operate on a single instance of the class.
Additionally the object will also define class A, and create all of the methods in object A as static methods on class A (for interfacing with Java) [2].
Therefore we can say that the static methods of Java class A access the same members as the Scala singleton instance, which per your definition then deserve to be called (static) methods of class A.
Of course, the main difference is - method can use static fields, not only method parameters.
But there is additional one - polymorphism!
Results of evaluation Class A.doTheSameStaticMethod() and ClassB.doTheSameStaticMehod() will be depends of class. In this case function is impotent.
Each class has an object to represent it that is an instance of a subclass of the Class class. Static methods are really instance methods on these objects that are instances of a subclass of Class. They have access to state in the form of static fields, so they are not restricted to being just (stateless) functions. They are methods.
I'm learning Java and I noticed that the main() is put inside of a class. Why? I don't consider my main() to be a member of any object. So please tell me how I can get around this.
I don't consider my main() to be a member of any object.
It's not since it's a static method. It does not belong to any object but to the class itself.
Aside from that, all methods, including main must be defined in classes.
More generally, a class is the smallest unit in compiled Java code and contains both information on instances of the class and behavioral code that runs by itself (e.g. the main method).
By nature, Java is highly object oriented. So everything must be encapsulated within a class. All methods must be placed inside of a class. However, the main() is different. There can only be one main function in a class and it must always be static, meaning it is not part of an object and there is only one instance of it. When a java application is executed, the JRE will look for the main class (i.e. the class containing the main function). main() is where the execution starts. But due to the very nature of OO, it must be placed in a class. You can say that this is simply because of the skeletal structure of java. No other reason in particular.
You must put the main() in a class. And, it must be static (which means it is not a member of any Object). When you launch the Java Runtime Environment (JRE) it will load that class and invoke the main().
This is covered by JLS-12.1 - Java Virtual Machine Startup which says in part,
The Java Virtual Machine starts execution by invoking the method main of some specified class, passing it a single argument, which is an array of strings. In the examples in this specification, this first class is typically called Test.
I know the definition of static which is a keyword to refer a variable or method to the class itself. Could this mean if I wrote a method called parseInt() in a class called calculator and another method called parseInt() in a different class called mathProgram, the compiler Eclipse will know which class the method parseInt() is referring to?
You need to call static methods by referencing the class it is a part of:
MathProgram.parseInt();
Is not the same as
Calculator.parseInt();
So written this way it is clear to the JVM which method you were referring to.
Edit: You can also call static methods using an instance variable but this is in bad form and should be avoided. See this SO answer for more info.
Edit2: Here's a link to the Java Coding Conventions section regarding the use of calling static methods from instance variables. (Thanks to Ray Toal for the link left in the answer to a question posted here)
Yes, because static methods and variables must be in a class and to call them outside of that class you need to qualify them.
For example Calculator.parseInt() and OtherClass.parseInt().
Eclipse uses that to tell them apart.
If the method is static, you need to call it using the classname:
Calculator.parseInt();
Otherwise, with an instance:
Calculator c = new Calculator();
c.parseInt();
Either way, its explicit which you want.