Cannot make a static reference to the non-static method - java

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.

Related

Why does my Java class work without using "this."? [duplicate]

This question already has answers here:
When should I use "this" in a class?
(17 answers)
Closed 3 years ago.
In my Java class I have made some attributes and methods. Within one of the methods I have called upon an attribute of the class, however, the method works both with and without using "this." in front of the attribute. If this is not necessary, I am wondering what is even the purpose of "this."
public String getName() {
return name;
}
^^ Works ^^
public String getName() {
return this.name;
}
^^ Works ^^
From https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html :
"The most common reason for using the this keyword is because a field
is shadowed by a method or constructor parameter."
The use of "this" is not mandatory. But it is useful to refer to a field of the object instead of a parameter of a method or a variable. See:
public class Person {
private String name = "John Smith";
public String getName() {
return name; // no need for keyword "this"
}
public String getFalseName() {
String name = "Bill Doe"; // this.name is shadowed
return name; // will return "Bill Doe" since keyword "this" is not used
}
public String getTrueName() {
String name = "Bill Doe"; // this.name is shadowed
return this.name; // Will return "John Smith";
}
public void setName( String name ){ // name is a parameter, this.name is shadowed now
this.name = name; // this.name is correctly assigned
}
}
The main purpose of 'this' keyword is calling the Instance method/variables using object reference of the current class without creating an object.
please follow the below code you will get a little bit clarification about this keyword.
please execute the below code and observe the difference.
public class Test {
private String name;
public String getName() {
return name;
}
public String getName2() {
return this.name;
}
public void setName(String name) {
//here I am asigning method parameter value to class level variable
this.name = name;
}
public void setName2(String name) {
//here Iam not using this keyword
//Here There is no use of assign name = name
name = name;
}
public static void main(String[] args) {
Test test = new Test();
test.setName("test 123");
System.out.println(test.getName());
System.out.println(test.getName2());
test.setName2("test 456");
System.out.println(test.getName());
System.out.println(test.getName2());
test.setName("test 789");
System.out.println(test.getName());
System.out.println(test.getName2());
}
}
Using this is a more direct way of referencing the attributes of the class. You have (correctly) found it is not necessary in this context. Here is a more useful example:
public String getName(String name) {
return this.name + " - " + name;
}
This will return the attribute name, followed by a hyphen, followed by the name passed into the parameter. By using the this keyword, you can specify exactly which variable you are referring to, even if they have the same name.
Keyword 'this' in Java is a reference variable that refers to the current object. It can be used to refer current class instance variable.
In your case if you write only name then it can refer to current method variable or argument if you write this.name then it will specifically point to current class instance variable.
Mainly this represent as instance of current class.
Purpose of this: it refers to the very object the method is part of.
Is this pointless? No. How do you otherwise pass the self object as another method's argument? For example, it is common to invoke a function like foo(this)

How can I refer the objcet that calls a method in the method in Java? [duplicate]

This question already has answers here:
When should I use "this" in a class?
(17 answers)
Closed 7 years ago.
I'm trying to get an understanding of what the the java keyword this actually does.
I've been reading Sun's documentation but I'm still fuzzy on what this actually does.
The this keyword is a reference to the current object.
class Foo
{
private int bar;
public Foo(int bar)
{
// the "this" keyword allows you to specify that
// you mean "this type" and reference the members
// of this type - in this instance it is allowing
// you to disambiguate between the private member
// "bar" and the parameter "bar" passed into the
// constructor
this.bar = bar;
}
}
Another way to think about it is that the this keyword is like a personal pronoun that you use to reference yourself. Other languages have different words for the same concept. VB uses Me and the Python convention (as Python does not use a keyword, simply an implicit parameter to each method) is to use self.
If you were to reference objects that are intrinsically yours you would say something like this:
My arm or my leg
Think of this as just a way for a type to say "my". So a psuedocode representation would look like this:
class Foo
{
private int bar;
public Foo(int bar)
{
my.bar = bar;
}
}
The keyword this can mean different things in different contexts, that's probably the source of your confusion.
It can be used as a object reference which refers to the instance the current method was called on: return this;
It can be used as a object reference which refers to the instance the current constructor is creating, e.g. to access hidden fields:
MyClass(String name)
{
this.name = name;
}
It can be used to invoke a different constructor of a a class from within a constructor:
MyClass()
{
this("default name");
}
It can be used to access enclosing instances from within a nested class:
public class MyClass
{
String name;
public class MyClass
{
String name;
public String getOuterName()
{
return MyClass.this.name;
}
}
}
"this" is a reference to the current object.
See details here
The keyword this is a reference to the current object. It's best explained with the following piece of code:
public class MyClass {
public void testingThis()
{
// You can access the stuff below by
// using this (although this is not mandatory)
System.out.println(this.myInt);
System.out.println(this.myStringMethod());
// Will print out:
// 100
// Hello World
}
int myInt = 100;
string myStringMethod()
{
return "Hello World";
}
}
It's not used a lot unless you have code standard at your place telling you to use the this keyword. There is one common use for it, and that's if you follow a code convention where you have parameter names that are the same as your class attributes:
public class ProperExample {
private int numberOfExamples;
public ProperExample(int numberOfExamples)
{
this.numberOfExamples = numberOfExamples;
}
}
One proper use of the this keyword is to chain constructors (making constructing object consistent throughout constructors):
public class Square {
public Square()
{
this(0, 0);
}
public Square(int x_and_y)
{
this(x_and_y, x_and_y);
}
public Square(int x, int y)
{
// finally do something with x and y
}
}
This keyword works the same way in e.g. C#.
An even better use of this
public class Blah implements Foo {
public Foo getFoo() {
return this;
}
}
It allows you to specifically "this" object in the current context. Another example:
public class Blah {
public void process(Foo foo) {
foo.setBar(this);
}
}
How else could you do these operations.
"this" keyword refers to current object due to which the method is under execution. It is also used to avoid ambiguity between local variable passed as a argument in a method and instance variable whenever instance variable and local variable has a same name.
Example ::
public class ThisDemo1
{
public static void main(String[] args)
{
A a1=new A(4,5);
}
}
class A
{
int num1;
int num2;
A(int num1)
{
this.num1=num1; //here "this" refers to instance variable num1.
//"this" avoids ambigutiy between local variable "num1" & instance variable "num1"
System.out.println("num1 :: "+(this.num1));
}
A(int num, int num2)
{
this(num); //here "this" calls 1 argument constructor within the same class.
this.num2=num2;
System.out.println("num2 :: "+(this.num2));
//Above line prints value of the instance variable num2.
}
}
The keyword 'this' refers to the current object's context. In many cases (as Andrew points out), you'll use an explicit this to make it clear that you're referring to the current object.
Also, from 'this and super':
*There are other uses for this. Sometimes, when you are writing an instance method, you need to pass the object that contains the method to a subroutine, as an actual parameter. In that case, you can use this as the actual parameter. For example, if you wanted to print out a string representation of the object, you could say "System.out.println(this);". Or you could assign the value of this to another variable in an assignment statement.
In fact, you can do anything with this that you could do with any other variable, except change its value.*
That site also refers to the related concept of 'super', which may prove to be helpful in understanding how these work with inheritance.
It's a reference of actual instance of a class inside a method of the same class.
coding
public class A{
int attr=10;
public int calc(){
return this.getA()+10;
}
/**
*get and set
**/
}//end class A
In calc() body, the software runs a method inside the object allocated currently.
How it's possible that the behaviour of the object can see itself? With the this keyword, exactly.
Really, the this keyword not requires a obligatory use (as super) because the JVM knows where call a method in the memory area, but in my opinion this make the code more readeable.
It can be also a way to access information on the current context.
For example:
public class OuterClass
{
public static void main(String[] args)
{
OuterClass oc = new OuterClass();
}
OuterClass()
{
InnerClass ic = new InnerClass(this);
}
class InnerClass
{
InnerClass(OuterClass oc)
{
System.out.println("Enclosing class: " + oc + " / " + oc.getClass());
System.out.println("This class: " + this + " / " + this.getClass());
System.out.println("Parent of this class: " + this.getClass().getEnclosingClass());
System.out.println("Other way to parent: " + OuterClass.this);
}
}
}
Think of it in terms of english, "this object" is the object you currently have.
WindowMaker foo = new WindowMaker(this);
For example, you are currently inside a class that extends from the JFrame and you want to pass a reference to the WindowMaker object for the JFrame so it can interact with the JFrame. You can pass a reference to the JFrame, by passing its reference to the object which is called "this".
Every object can access a reference to itself with keyword this (sometimes called the this
reference).
First lets take a look on code
public class Employee {
private int empId;
private String name;
public int getEmpId() {
return this.empId;
}
public String getName() {
return this.name;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public void setName(String name) {
this.name = name;
}
}
In the above method getName() return instance variable name.
Now lets take another look of similar code is
public class Employee {
private int empId;
private String name;
public int getEmpId() {
return this.empId;
}
public String getName() {
String name="Yasir Shabbir";
return name;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public void setName(String name) {
this.name = name;
}
public static void main(String []args){
Employee e=new Employee();
e.setName("Programmer of UOS");
System.out.println(e.getName());
}
}
Output
Yasir Shabbir
this operator always work with instance variable(Belong to Object)
not any class variable(Belong to Class)
this always refer to class non static attribute not any other parameter or local variable.
this always use in non static method
this operator cannot work on static variable(Class variable)
**NOTE:**It’s often a logic error when a method contains a parameter or local variable that has the
same name as a field of the class. In this case, use reference this if you wish to access the
field of the class—otherwise, the method parameter or local variable will be referenced.
What 'this' does is very simply. It holds the reference of current
object.
This keyword holds the reference of instance of current class
This keyword can not be used inside static function or static blocks
This keyword can be used to access shadowed variable of instance
This keyword can be used to pass current object as parameter in function calls
This keyword can be used to create constructor chain
Source: http://javaandme.com/core-java/this-word

Printing an Array that Includes Inheritance members?

I have this issue with my code.
I create a class Employee with two instance variables:
private String name, department;
And afterwards I create another class called Tradesman whichc is an extension of Employee, but with one extra instance variable:
private String trade;
Now what I did is I created a print() method that will: A) in Employee class, print the name and department. B) same method used in Employee, will be created in Tradesman (thus overriding it) that will print extra one element which is the trade. Now the thing is that I create another class called Staff which will contain an array of type Object of some elements, and I have to implement a hire() method, fire() method and a put() method which will print the entire array. Everything is cool and wicked up till the moment of printing. I'm struggling with how to print it, since I have print() method for each class but it must be dependedn on the type... If i cast the method to Employee I will lose the trade element of Tradesman Class, ex:
void put(){
for (Object a:objArray){
((Employee)a).print();
}
}
Which is WRONG. Cause if I hire a Tradesman, this method won't print the Trade. How to deal with this problem? Thanks in advance! Cheers ^^
"Cause if I hire a Tradesman, this method won't print the Trade"
You're wrong, it will. If Employee is actually a Tradesman, calling print() will call Tradesman.print(). If it's overriden, then the overriding method will be called. If all your array objects are Employee, just use an Employee[] instead of Object[] so you don't have to do that useless casting.
"I want to implement an array of both Tradesman and Employee... One array that will contain both, Tradesman and Employee combined."
Employee[] will hold both since a Tradesman is an Employee. Also in Java I suggest you work with a List (List<Employee> in your case), it's more manageable than an array.
Even if you cast a Tradesman to Employee the underlying object will still be of type Tradesman and use the overridden print method.
try this
import java.util.ArrayList;
class Employee {
String name,department;
public Employee(String name, String department) {
this.name = name;
this.department = department;
}
public void print() {
System.out.println("Name: " + this.name);
System.out.println("Department: " + this.department);
}
}
class Tradesman extends Employee {
String trade;
public Tradesman(String name, String department, String trade) {
super(name,department);
this.trade = trade;
}
public void print() {
super.print();
System.out.println("Trade: " + this.trade);
}
}
class Staff {
ArrayList<Employee> empArray = new ArrayList<Employee>();
public void put() {
for(Employee emp : empArray) {
emp.print();
}
}
public static void main(String[] arg) {
Staff s = new Staff();
s.empArray.add(new Employee("John","Sales"));
s.empArray.add(new Tradesman("Jacob","Sales","Computers"));
s.put();
}
}

Real life scenarios for calling a constructor from another constructor

I know it is possible to call one constructor from another constructor via the use of "this".
But I would like to know is, why do we do it (i.e calling a constructor from another constructor)
Can anyone relate a simple example of where this might be actually useful ?
ArrayList is a nice example. The default constructor calls the constructor that takes the initial capacity of the underlying array. This looks like this:
public ArrayList()
{
this(10);
}
public ArrayList(int capacity)
{
objects = new Object[capacity];
}
If we do not want to duplicate code:
class Foo{
int requiredParam;
String name;
double optionalPrice;
Object extraObject;
public Foo(int rp, String name){
this.requiredParam=rp;
this.name=name
}
public Foo(int rp, String name, double op, Object e){
this(rp, name);
this.optionalPrice=op;
this.extraObject=e;
}
How about a simple class like this:
class Person {
String name;
Person(String firstName, String lastName) {
this(firstName + lastName);
}
Person(String fullName) {
name = fullName;
}
}
Different constructors give you the freedom of creating similar objects in different flavors.

non static variable name cannot be referenced from a static context [duplicate]

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.

Categories