So I have two classes:
A Main class with the public static void main(String args[]) method
and a Voice class that accesses a static variable from that class.
Within the main class are methods that are used by itself, and are required to be static along with some of its variables.
So I have a static variable within the Main class (that's created/filled in the public static void main(String args[]) method. That's why this case is special) which the other class should be able to access.
Here is an example of what's happening:
public class Main(){
public static int variable;
/*
Unrelated methods go here.
*/
public static void main(String args[]){
Voice v = new Voice();//This is just here for the code to make sense.
variable = 5;
v.doSomething();
}
}
public class Voice(){
public void doSomething(){
System.out.println(Main.variable);
}
}
Upon calling the doSomething() method in Voice, it leads to a nullPointerException.
I could fix this by passing on the variable variable to the Voice class, but is there a more easy way to fix this in the long run, if for instance, I needed to use more than one static variable from the Main class?
Your code is having syntax error. You can use this
class Main{
public static int variable;
/*
Unrelated methods go here.
*/
public static void main(String args[]){
Voice v = new Voice();//This is just here for the code to make sense.
variable = 5;
v.doSomething();
}
}
class Voice{
public void doSomething(){
System.out.println(Main.variable);
}
}
Output will be 5
You should do as follows
public class Main{
public static int variable;
/*
Unrelated methods go here.
*/
public static void main(String args[]){
Voice v = new Voice();//This is just here for the code to make sense.
variable = 5;
v.doSomething();
}
}
class Voice{
public void doSomething(){
System.out.println(Main.variable);
}
}
Related
When calling out the function testFunc(), I am not using the syntax
Apples.testFunc(). Yet the code runs successfully. How so?
class Apples {
public static void main(String args[] ) {
testFunc();
}
public static void testFunc() {
System.out.println("Hello world!");
}
}
Since, the static method is in the same class. So, you don't need to specify the class name.
If it is in different class, then you need to specify the class name.
Remember: Non-static methods can access both static and non-static members whereas static methods can access only static members.
For example :
Calling a static method present in different class, you need to do like this :
import com.example.Test;
public class Apples {
public static void main(String args[]) {
Test.testFunc();
}
}
package com.example;
public class Test {
public static void testFunc() {
System.out.println("Hello world!");
}
}
Your function testFunc() is in same class where the function main is. So you don't need to use class name before function testFunc().
When the memory is allocated for the class, Static method or static variable is assigned memory within a class. So we can access static member function or data variable using class name.
we can call static function as below
class Main1 {
public static void main(String args[] ) {
Main1.testFunc();
}
public static void testFunc() {
System.out.println("Hello world!");
}
}
or
class Main1 {
public static void main(String args[] ) {
testFunc();
}
public static void testFunc() {
System.out.println("Hello world!");
}
}
the answer will be same, but when static function is in other class then we must use classname to call it
I am new to java. I am currently reading some articles about static variables. When I am trying to implement my learnings, I encountered a problem about static variables. Here is the first code sample.
public class Human {
// in Human.java
public static int population = 0;
public static void main(String[] argv) {
System.out.println(population);
}
}
This code works fine and the outcome is 0.
But for the following code, I wasn't allow to compile it.
public class Human {
// in Human.java
public class Charlie extends Human {
public static int number = 0;
}
public static void main(String[] argv) {
System.out.println(new Human().new Charlie().number);
}
}
An error occurred: The field number cannot be declared static in a non-static inner type, unless initialized with a constant expression
I am confused with this situation. For the first code sample, my Human class is non-static and I was allowed to declare a static variable inside it. How come I can't do the same for my second code sample.
Any help would be appreciated. Thanks. :)
Try with public static final int number = 0; because Java does not let you define non-final static fields inside function-local inner classes. Only top-level classes and static nested classes are allowed to have non-final static fields.
From the JLS section 8.1.3:
Inner classes may not declare static members, unless they are constant variables (ยง4.12.4), or a compile-time error occurs.
Other way to make inner class static and access it
public class Human {
// in Human.java
public static class Charlie extends Human {
public static int number = 0;
}
public static void main(String[] argv) {
System.out.println(new Human.Charlie().number);
}
}
Can anyone tell me the use of making main method as final in java.
while this is allowed in java
public static final void main(String[] args) {
}
I dont see any use of making it final. anyways it is static so we can not override it.
Adding final to a static method can actually make a difference. Consider the following code:
class A {
public static void main(String[] args) {
System.out.println("A");
}
}
class B extends A {
public static void main(String[] args) {
System.out.println("B");
}
}
class C extends B {
}
public class Test {
public static void main(String[] args) {
C.main(args); // Will invoke B.main
}
}
Adding final to A.main would prevent accidental hiding of A.main. In other words, adding final to A.main guarantees that B.main is not allowed, and that C.main therefore prints "A" as opposed to for instance "B".
Why are we allowed to have a final main method in java?
Beside the above corner case, adding final to a static method doesn't make much difference, so I don't see a big point in adding a rule for disallowing it.
More information available here: Behaviour of final static method
I surprisingly find this confusing. I must be missing something.
So I have this simple syntax
public class OMG{
public static void main(String args[]){
int hi=2;
letsDoIt();
System.out.println(hi);
}
public static void letsDoIt(){
hi+=1;
}
}
Obviously this cause an error, since hi is a local variable.
Judging from my experience from python I added this
public class OMG{
public static void main(String args[]){
int hi=2;
letsDoIt();
System.out.println(hi);
}
public static void letsDoIt(){
this.hi+=1;
}
}
Which adds extra error when non-static variable cannot be accessed from a static method.
I added static to hi
public class OMG{
public static void main(String args[]){
static int hi=2;
letsDoIt();
System.out.println(hi);
}
public static void letsDoIt(){
this.hi+=1;
}
}
The compiler scolds me for a illegal expression. I substitute the static with private (which some SO answers, recommend) but same error.
Where's my mistake? Is there any way I can solve this, without making global class?
You cannot declare static variables inside a method because static modifier means that a method or field belongs to the class.
The easiest solution to this problem would be to declare the variable as static class variable. Using this approach, you also need to remove this from this.hi in lestDoIt method. The code would be like this:
public class OMG {
static int hi=2;
public static void main(String args[]) {
letsDoIt();
System.out.println(hi);
}
public static void letsDoIt() {
hi+=1;
}
}
Another solution may be using a non static variable hi. This would need you to also remove the static modifier to the letsDoIt method to access to hi field, because static methods cannot access to instance fields because, as explained above, static means that a method or field belongs to the class and not to a specific object instance of the class.
The solution would be:
public class OMG {
int hi=2;
public static void main(String args[]) {
//note that we have to create a new instance of OMG
//because, again, static methods cannot access to non-static methods/fields
OMG omg = new OMG();
omg.letsDoIt();
System.out.println(omg.hi);
}
public void letsDoIt() {
this.hi+=1;
}
}
More info:
Java Tutorials. Using the this Keyword
Java Tutorials. Understanding Class Members
There are two elements causing your issue.
variable hi must be referenced within a shared context between your main method and your letsDoIt method
because your main method is static, and so your letsDoIt, the will only have visibility on static fields (unless passed an instance as argument, that is)
Hence:
Declare hi as a static field of OMG:
public class OMG {
static int hi;
...
Remove the local variable declaration in your main method.
Reference it with OMG.hi or just hi within a static context, not with this.hi as this implies an instance of Main, which is not visible from a static context
You can not do "this.hi+=1" in a static context and in order to access the hi variable from "letsDoIt()" you have to declare it as a class variable like I did in the code below:
public class OMG{
public static int hi;
public static void main(String args[]){
hi=2;
letsDoIt();
System.out.println(hi);
}
public static void letsDoIt(){
hi+=1;
}
}
Static variables are variables of the class, not its instances. You can't have a static variable inside a method.
To fix this error, move hi outside the main method (keeping it static). Also get rid of the this in letsDoIt().
public class OMG {
static int hi=2;
public static void main(String args[]){
letsDoIt();
System.out.println(hi);
}
public static void letsDoIt() {
hi+=1;
}
}
It is said that non-static variables cannot be used in a static method. But public static void main does. How is that?
No, it doesn't.
public class A {
int a = 2;
public static void main(String[] args) {
System.out.println(a); // won't compile!!
}
}
but
public class A {
static int a = 2;
public static void main(String[] args) {
System.out.println(a); // this works!
}
}
or if you instantiate A
public class A {
int a = 2;
public static void main(String[] args) {
A myA = new A();
System.out.println(myA.a); // this works too!
}
}
Also
public class A {
public static void main(String[] args) {
int a = 2;
System.out.println(a); // this works too!
}
}
will work, since a is a local variable here, and not an instance variable. A method local variable is always reachable during the execution of the method, regardless of if the method is static or not.
Yes, the main method may access non-static variables, but only indirectly through actual instances.
Example:
public class Main {
public static void main(String[] args) {
Example ex = new Example();
ex.variable = 5;
}
}
class Example {
public int variable;
}
What people mean when they say "non-static variables cannot be used in a static method" is that non-static members of the same class can't be directly accessed (as shown in Keppils answer for instance).
Related question:
Accessing non-static members through the main method in Java
Update:
When talking about non-static variables one implicitly means member variables. (Since local variables can't possible have a static modifier anyway.)
In the code
public class A {
public static void main(String[] args) {
int a = 2;
System.out.println(a); // this works!
}
}
you're declaring a local variable (which typically is not referred to as non-static even though it doesn't have a static modifier).
The main method does not have access to non-static members either.
final public class Demo
{
private String instanceVariable;
private static String staticVariable;
public String instanceMethod()
{
return "instance";
}
public static String staticMethod()
{
return "static";
}
public static void main(String[] args)
{
System.out.println(staticVariable); // ok
System.out.println(Demo.staticMethod()); // ok
System.out.println(new Demo().instanceMethod()); // ok
System.out.println(new Demo().instanceVariable); // ok
System.out.println(Demo.instanceMethod()); // wrong
System.out.println(instanceVariable); // wrong
}
}
This is because by default when you call a method or variable it is really accessing the this.method() or this.variable. But in the main() method or any other static method(), no "this" objects has yet been created.
In this sense, the static method is not a part of the object instance of the class that contains it. This is the idea behind utility classes.
To call any non-static method or variable in a static context, you need to first construct the object with a constructor or a factory like your would anywhere outside of the class.
More depth:
Basically it's a flaw in the design of Java IMO which allows static members (methods and fields) to be referenced as if they were instance members. This can be very confusing in code like this:
Thread newThread = new Thread(runnable);
newThread.start();
newThread.sleep(1000);
That looks like it's sending the new thread to sleep, but it actually compiles down into code like this:
Thread newThread = new Thread(runnable);
newThread.start();
Thread.sleep(1000);
because sleep is a static method which only ever makes the current thread sleep.
Indeed, the variable isn't even checked for non-nullity (any more; it used to be, I believe):
Thread t = null;
t.sleep(1000);
Some IDEs can be configured to issue a warning or error for code like this - you shouldn't do it, as it hurts readability. (This is one of the flaws which was corrected by C#...)
**Here you can see table that clear the access of static and non-static data members in static and non-static methods. **
You can create non-static references in static methods like :
static void method() {
A a = new A();
}
Same thing we do in case of public static void main(String[] args) method
public class XYZ
{
int i=0;
public static void increament()
{
i++;
}
}
public class M
{
public static void main(String[] args)
{
XYZ o1=new XYZ();
XYZ o2=new XYZ();
o1.increament();
XYZ.increament(); //system wont be able to know i belongs to which object
//as its increament method(static method)can be called using class name system
//will be confused changes belongs to which object.
}
}