This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 5 years ago.
class Singer
{
String name;
String album;
public Singer(){
name="Whitney Houson";
album="Latest Releases";
}
public static void main(String[] args)
{
System.out.println("Name of the singer is "+name);
System.out.println("Album Information stored for "+album);
}
}
When i run this code i am finding error which says that non static variable name cannot be referenced from a static context
That's because the variables name and album do not exist in the main procedure, because it's static, which means it cannot access instance-level members. You will need an instance of the Singer class, like this:
public static void main(String[] args) {
Singer s = new Singer();
System.out.println("Name of the singer is " + s.name);
System.out.println("Album information stored for " + s.album);
}
However, unless you declare your name/album members with a public access modifier, the above code will fail to compile. I recommended writing a getter for each member (getName(), getAlbum(), etc), in order to benefit from encapsulation. Like this:
class Singer {
private String name;
private String album;
public Singer() {
this.name = "Whitney Houston";
this.album = "Latest Releases";
}
public String getName() {
return this.name;
}
public String getAlbum() {
return this.album;
}
public static void main(String[] args) {
Singer s = new Singer();
System.out.println("Name of the singer is " + s.getName());
System.out.println("Album information stored for " + s.getAlbum());
}
}
Another alternative would be to declare name and album as static, then you can reference them in the way you originally intended.
A non-static member or class needs to be instanced in order to exist. Then, accessing a non-static member or object from a static member does not guarantee that this member or object is instantiated, then access to it is impossible.
You will need to create an instance of your non-static object within your static context to make it.
class Singer {
String name;
String album;
// You will need the following to make your code compile,
// and the call to these getters within your 'main' function.
public getName() {
return name;
}
public getAlbum() {
return album;
}
public Singer() {
name="Whitney Houson";
album="Latest Releases";
}
}
public static void main(String[] args) {
Singer singer = new Singer();
System.out.println("Name of the singer is " + singer.getName());
System.out.println("Album Information stored for " + singer.getAlbum());
}
This way, you include the instantiation of the Singer object into a static object, thuis assuring it is instantiated properly before it is accessed.
Main is a static method. Instance variables (variables defined in the class but not marked as static) cannot be accessed from a static method without referencing an instance of the class.
public static void main(String[] args)
{
Singer singer = new Singer();
System.out.println("Name of the singer is " + singer.name);
System.out.println("Album Information stored for " + singer.album);
}
One option is what Chris Hutchinson mentioned. The other one is to declare them static.
main is a static method. So name and album have to be declared as static.
private static String name;
private static String album;
To expand more on Chris' answer, you can technically have as many instances of the Singer class as your memory can support, but there is only ever one instance of the main function running. This means that attempting to access those variables from the static function means it has no idea which instance of the variable it should be accessing, hence the error.
You can make the variables local to the main function, but that would probably defeat the purpose of the program then since logic would dictate there can be more than one singer (most likely). A better plan of attack would be to create a generic class that houses the main function, and then create a Singer class within that (or elsewhere) and instantiate X instances of that class in your main function and go from there.
Related
I am trying to learn how constructors work and I have been trying to debug this simple java program but I cannot get it to run. Eclipse simple refuses to acknowledge its presence and just runs an earlier project. Any ideas would be very gratefully received - I am struggling to see what I have done wrong.
package timber;
public class Person {
private String firstName;
private String lastName;
private String address;
private String username;
public Person(String personFirstName, String personLastName, String personAddress, String personUsername)
{
firstName = personFirstName;
lastName = personLastName;
address = personAddress;
username = personUsername;
}
public void displayPersonDetails()
{
System.out.println("Name: " + firstName + " " + lastName);
System.out.println("Address: " + address);
System.out.println("Username: " + username);
}
}
I then have a second class that contains the main method
package timber;
public class PersonExample {
public void main(String[] args) {
Person dave = new Person("Dave", "Davidson", "12 Main St.", "DDavidson");
dave.displayPersonDetails();
}
}
could you please add static in main method :-
public static void main(String[] args) {
Person dave = new Person("Dave", "Davidson", "12 Main St.", "DDavidson");
dave.displayPersonDetails();
}
Your main method always needs to be static.
See Why is the Java main method static?
Replace,
public void main(String[] args)
with
public static void main(String[] args)
Your main method needs to be 'static'. Why? If you want to call a method in Java, there are two ways
Create an instance of class and use that object to call it's methods
Make a method 'static' so that you can call the method using the class name and no instance creation needed.
The 'main' method, if non-static (like in your case) you have to create an instance of it's class to call. But, where would you create an instance of that class, where your main method is residing? Create another class and call from there? and create yet another class to call this class? It will never end. I mean there has to be a starting point right?
By giving the method the name 'main' and by adding the keyword 'static' in it's signature, you help JVM call that method without the need to an create instance.
Just change
public void main(String[] args)
to
public static void main(String[] args)
Everything is fine you have just missed the static keyword .
Instead of
public void main(String [] args)
Use
public static void main(String[] args)
Its said that, statics are much comfortable with statics in java. I'm trying to achieve small thing there where I want to change outer's class static variable value using inner static class's instance for that specific instance only. I think its a ideal case. If not please share with me. And moreover all inner classes have access to outer class's members.
So here is my code.
package org;
import org.Outerclass.innerclass;
public class Outerclass {
static String name = "Europe";
String getname() {
return name;
}
public void setname(String name) {
this.name = name;
System.out.println(this.name);
}
void setstaticname() {
Outerclass.innerclass i = new Outerclass.innerclass();
i.name = "London"; // Error "name cannot be resolved or is not a field" ?
System.out.println(i.name);
}
static class innerclass {
void updatename() {
Outerclass o = new Outerclass();
o.setname("USA");
}
}
public static void main(String[] args) {
innerclass p = new innerclass();
System.out.println(p.name); // Error "name cannot be resolved or is not a field" ?
}
}
I have tried in two ways and vice versa but same errors. Any suggestions ?
name is a member of OuterClass. And you are trying to access it using innerclass instance. That's why you are getting this error.
Also what is this + here System.out.println(+p.name); ?
Edit:
From inner class you can access outer class static members just like below:
name = "";
or
Outerclass.name = "";
change +p.name to name or OuterClass.name. + inside System.out.println will give you another compile time error.
static members are not available in object level they are available in class level. static are initialized at compile time where object is created at run time
i.name should be Outerclass.name since name is a member of Outerclass and not innerclass
in your code, i is an instance of innerclass.
I have a class with static variables as:
class Commons {
public static String DOMAIN ="www.mydomain.com";
public static String PRIVATE_AREA = DOMAIN + "/area.php";
}
And if I try to change DOMAIN from an Android Activity (or another java class) at runtime, the DOMAIN variable change but PRIVATE_AREA don't change. Why?
This is because the assignment of static fields happens once the class is loaded (occurs only one time) into the JVM. The PRIVATE_AREA variable will not be updated when the DOMAIN variable is changed.
public class Test {
public static String name = "Andrew";
public static String fullName = name + " Barnes";
public static void main(String[] args){
name = "Barry";
System.out.println(name); // Barry
System.out.println(fullName); // Andrew Barnes
}
}
I suggest that you use the following structure.
public class Test {
private static String name = "Andrew";
public static String fullName = name + " Barnes";
public static void setName(String nameArg) {
name = nameArg;
fullName = nameArg + " Barnes";
}
}
Test2.java
public class Test2 {
public static void main(String[] args){
System.out.println(Test.fullName); // Andrew Barnes
Test.setName("Barry");
System.out.println(Test.fullName); // Barry Barnes
}
}
This is because Static variables are initialized only once , at the start of the execution.
See more at: http://www.guru99.com/java-static-variable-methods.html
PRIVATE_AREA did't change because it is set on declaration time. When You change DOMAIN, it has no effect on PRIVATE_AREA.
Maybe it is better to work with setter(...) and getter() Methods and local variables. On getting PRIVATE_AREA You create the retrun value again.
Assignment of variable happens at the load time of class thats why after that if you change the value of one static variable, it will not reflect there where it is assigned to another variable
I am a new-bee to Java.
I know, even a sub-class can not refer a non-static member of a base class directly.
like,
class BaseClass
{
int id;
public void testMethod()
{
System.out.println("Hello");
}
}
public class Test1 extends BaseClass
{
public static void main(String[] args)
{
System.out.println("ID : " + id);
}
}
This will give us an error "Cannot make a static reference to the non-static field id"
But, in case of abstract class, we can do it.
abstract class MyAbstractClass
{
int id;
public void setId(int id)
{
this.id = id;
}
}
public class SubClass extends MyAbstractClass
{
public void testMethod()
{
System.out.println("ID Value : " + id);
}
public static void main(String[] args)
{
SubClass obj = new SubClass();
obj.setId(1);
obj.testMethod();
}
}
I was wondering how and why is it possible in case of abstract class.
Appreciate your answers.
Please be gentle, I am a new-bee to java. :)
The problem you stated does not depend on abstract classes but on static and nonstatic contexts. You simply make two different calls to the instance variable.
The first example tries to access id from a static context which is not allowed and you get your error (Cannot make a static reference to the non-static field id).
public static void main(String[] args)
{
System.out.println("ID : " + id);
}
In the second example, you create an instance of your class and from within this instance you are able to access id. This is a reference from a nonstatic context.
public void testMethod()
{
System.out.println("ID Value : " + id);
}
So you achieve the same for your first example, if you create an instance like in the second and access id from a nonstatic method..
Cannot make a static reference to the non-static field id
This error appears because you want to access to a non-static field inside a static method. And that's what you're doing here: main method is static, but id is not.
public static void main(String[] args) {
//here you don't create an instance of the class
//you cannot access to id directly
System.out.println("ID : " + id);
}
You need to create an instance of the class to access to its non-static fields, as you did in the second example, regardless if you're extending from other (abstract) class or not.
public static void main(String[] args) {
//here you create an instance of the class
SubClass obj = new SubClass();
obj.setId(1);
obj.testMethod();
}
I have searched for this problem and found many answers regarding it but however i did not understand them , i would a clarification regarding my own code so hopefully it will makes sense
i am trying to call the PrintList method in the main method
but i get this error
Cannot make a static reference to the non-static method PrintList() from the type Stack
if i change the modifier of PrintList to static , it ruins the whole code.
can anyone help me fix this issue please?
Thanks
public class Stack<Item> {
public int N; // size of the stack
public Node<Item> first; // top of stack
public Node<Item> last; // top of stack
// helper linked list class
private static class Node<Item> {
private Item item;
private Node<Item> next;
}
public Stack() {
first = null;
last = null;
N = 0;
}
public void PrintList() {
Node<Item> current;
current = first;
while (current.next != null) {
System.out.println(current.item);
current = current.next;
}
}
public static void main(String[] args) {
// Declare the stack
Stack<String> s = new Stack<String>();
s.push("Bob");
s.push("Mary");
s.push("David");
s.InsertBegin("George");
System.out.println("First item: " + s.peek());
Object current;
PrintList(); // what is wrong here?
}
}
The problem is that you are not specifying the instance that PrintList is to be called on. To fix that, change this:
PrintList(); // what is wrong here?
to this:
s.PrintList();
What you really need is to understand exactly what static and non-static actually mean.
First, some background. Apologies if some of this is already familiar to you. Java is an object oriented language, you create a class to act as a template for a specific type of object, defining what attributes (variables) that it has, and how it behaves (methods). These attributes and behaviours belong to objects of that class:
public class Person {
private String forename;
private String surname;
public Person(String forename, String surname) {
this.forename = forename;
this.surname = surname;
}
public String getFullName() {
return forename + " " + surname;
}
public static void main(String[] args) {
Person john = new Person("John", "Doe");
}
}
The above code defines a template for creating objects of the type Person, each having a forename and a surname, both of the type String. It also defines a behaviour that allows you to get a Person's full name using the getFullName() method.
Both forename and surname, as well as getFullName() are examples of non-static fields/methods. That is, they belong to a specific Person object. Importantly: none of these can exist without a Person object being created first. In this case we have a Person object called john which has a forename of "John" and a surname of "Doe". If we were to call john's getFullName() method:
john.getFullName();
Then we'd get "John Doe" back.
The opposite of this is static. Static things do not belong to an object, instead, they belong to a class.
public class Person {
private String forename;
private String surname;
private static String species = "Homo sapiens";
public Person(String forename, String surname) {
this.forename = forename;
this.surname = surname;
}
public String getFullName() {
return forename + " " + surname;
}
public static void main(String[] args) {
Person john = new Person("John", "Doe");
}
}
Here the String species doesn't belong to john, it belongs to Person. Static methods and variables don't need an object in order to exist, they always* exist. You access it by using the class itself as a reference, like this:
Person.species;
In your example, you have defined a method PrintList() as a behaviour of objects of the Stack<Item> class. The problem is that you're inside the main method, which is static. This means that you aren't in the 'context' of an object (because main belongs to Stack<Item>, not objects of the type Stack<Item>) when you're trying to call the PrintList() method. When you're inside a static method, in order to call a non-static method or access a non-static attribute, you must do so using a reference to an object of the class that owns it. In your case, you already have this reference in the form of s, so you can call your PrintList() method like so:
s.PrintList();
NB: Conventionally in Java we use camelCase for method names, so it really should be printList().
When I first started to learn Java, I found the concept of static very difficult to wrap my head around - because I hadn't learned to think in an object-oriented way yet. When the penny drops, you'll wonder why you ever struggled with it. Hopefully this will help you get closer towards that penny-drop moment!
*As long as the class is loaded and it's not a compile-time constant (but you don't need to worry about those yet).
You can call static methods like this:
ClassName.methodToCall();
You can call non-static methods like this:
ClassName classInstance = new ClassName();
classInstance.methodToCall();
Since your method PrintList() is non-static as it should be in this case, you should call it on an instance.