Why is Eclipse suggesting I make my method static - java

I am calling a method from a class and it gives me an error to make the method static. I am confused about why, as I asked this question What's the difference between a class variable and a parameter in a constructor? and my understanding was that class variables were made static.
Patient class:
public String setOption(String option) throws IOException
{
option = stdin.readLine();
//stuff here
return option;
}
Patient management system:
public class PatientManagementSystem
{
static BufferedReader stdin = new BufferedReader(new InputStreamReader(
System.in));
public static void main(String[] args) throws IOException
{
Patient.setOption(null);
}
}
The error:
Do I change the method to static or create a local variable?

Based on your earlier question, I think may not be fully digging the concept of the local variable. In this method:
public String setOption(String option) throws IOException
{
option = stdin.readLine();
return option;
}
option is a local variable. You pass the initial value for that variable as an argument to the setOption method each time you call it (and you happen to ignore that value), but with that detail out of the way, this is the same as
public String setOption() throws Exception
{
String option = stdin.readLine();
return option;
}
Now, local variables are something completely different from instance or class variables: they are valid only within a method body, and exist only during the time that method is executing. With that in mind, let's look at this code:
static BufferedReader stdin = new BufferedReader(new InputStreamReader(
System.in));
public static void main(String[] args) throws IOException
{
Patient.setOption(null);
}
Here you are basically misusing a class variable stdin for something which should have been a local variable:
public static void main(String[] args) throws IOException
{
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
Patient.setOption(null);
}
On to the question of your method call... setOption is currently an instance method, which means it must be called in the context of an instance. You are calling it as-is, with no instances of Patient involved. If you continue down this road, you won't be able to represent more than a single patient, probably not your idea. So you want to keep the method as it is and create an instance of Patient:
Patient p = new Patient();
p.setOption(...);
In your overall design it is not clear what role setOption should play, but it is not a good idea that it uses the static stdin variable (I already made it local above). You want to pass any data read from stdin into the setOption method and thus decouple it from the input reading logic.

You (probably) need to create an object of the Patient class.
Patient myPatient = new Patient();
myPatient.setOption(null);
It's hard to necessarily know what you want to do with such limited information. I don't know what you intend to do with the Patient class, but my best guess? It makes sense to do it this way, given you're trying to call a method with a setter naming convention.
If you don't intend to instantiate an object and go the route of making setOption a static method, then you should probably change the method name.
With a more in-depth explanation of what exactly you're trying to accomplish (not even talking pseudo-code, just a very abstract idea of what you're trying to do), it would be easier to explain more about static here (with your specific example) and what you should be doing, etc.

Do I change the method to static or create a local variable?
Both is OK.
If your method doesn't use class variables, it's better to make it static, so you do not have to instantiate the class for the method call.

The question of when to make something static vs. non-static is based on the real-world object/concept being modeled. Let's take the example of the Patient object in this code. Without seeing any code about the Patient, it's still pretty clear what a Patient is and what it represents. So, at its simplest:
If you're doing something with a particular Patient (let's say Jane Doe), then it's not static. It's operating on an instance of a Patient.
If you're doing something regarding the concept of a Patient, then it's static.
So some non-static operations might be:
Update the Patient's name
Admit/discharge the Patient from a hospital
Transfer the Patient to a different Doctor
All of these would involve a specific Patient, which would have been initialized somewhere:
var janeDoe = new Patient("Jane Doe");
// ...
janeDoe.TransferTo(doctorSmith);
I'm actually having trouble thinking of some static methods for a Patient. The most common example of a static method is probably a factory method, where you get an existing Patient or collection of Patients. Something like:
var janeDoe = Patient.Fetch("Jane Doe");
or:
var todaysPatients = Patient.Fetch(DateTime.Today);
Various helper methods are often static as well, perhaps a method on the Patient object which accepts a MedicalRecord object and converts it to a different format, for example.
But the overall idea is the same. If you're interacting with a specific instance of an object, then you need an instance of that object to represent that real-world concept.

Because you are directly calling that method without creating object of class.
When to have static methods?

To call a method in a static way, you have to make it static :
public static String setOption(String option) throws IOException
But in your example if stdin is not a static member of your Patient class, it can't work.
To sum up, you can call a method the way you call it when it's declared static. In a static method you can access only static members of your class.

Try this in your main method :
Patient myPatient = new Patient();
myPatient.setOption(null);

We create classes with static methods when we intend to use those methods as utility methods, like parseInt in the class Integer. thus either modify the method
public static String setOption(String option) throws IOException // STATIC
{
option = stdin.readLine();
//stuff here
return option;
}
and then use the method like
Patient.setOption(null);
OR instantiate an object for Patient like
Patient obj = new Patient();
obj.setOption(null);

In Java main method is special. It's the starting point of your code. Static methods could be called from anywhere in your code. Thus actually it does not belong to the containing class. It's also true for the main method.
Thus you should construct your object in the main method and then use the constructed instance's methods. If you do not construct your an instance, then your ide will recognise the error and suggest you to make it static.

Related

Cannot make a static reference to the non-static method setContentPane(Container) from the type JFrame [duplicate]

Building a multi-language application in Java. Getting an error when inserting String value from R.string resource XML file:
public static final String TTT = (String) getText(R.string.TTT);
This is the error message:
Error: Cannot make a static reference to the non-static method getText(int) from the type
Context
How is this caused and how can I solve it?
Since getText() is non-static you cannot call it from a static method.
To understand why, you have to understand the difference between the two.
Instance (non-static) methods work on objects that are of a particular type (the class). These are created with the new like this:
SomeClass myObject = new SomeClass();
To call an instance method, you call it on the instance (myObject):
myObject.getText(...)
However a static method/field can be called only on the type directly, say like this:
The previous statement is not correct. One can also refer to static fields with an object reference like myObject.staticMethod() but this is discouraged because it does not make it clear that they are class variables.
... = SomeClass.final
And the two cannot work together as they operate on different data spaces (instance data and class data)
Let me try and explain. Consider this class (psuedocode):
class Test {
string somedata = "99";
string getText() { return somedata; }
static string TTT = "0";
}
Now I have the following use case:
Test item1 = new Test();
item1.somedata = "200";
Test item2 = new Test();
Test.TTT = "1";
What are the values?
Well
in item1 TTT = 1 and somedata = 200
in item2 TTT = 1 and somedata = 99
In other words, TTT is a datum that is shared by all the instances of the type. So it make no sense to say
class Test {
string somedata = "99";
string getText() { return somedata; }
static string TTT = getText(); // error there is is no somedata at this point
}
So the question is why is TTT static or why is getText() not static?
Remove the static and it should get past this error - but without understanding what your type does it's only a sticking plaster till the next error. What are the requirements of getText() that require it to be non-static?
There are some good answers already with explanations of why the mixture of the non-static Context method getText() can't be used with your static final String.
A good question to ask is: why do you want to do this? You are attempting to load a String from your strings resource, and populate its value into a public static field. I assume that this is so that some of your other classes can access it? If so, there is no need to do this. Instead pass a Context into your other classes and call context.getText(R.string.TTT) from within them.
public class NonActivity {
public static void doStuff(Context context) {
String TTT = context.getText(R.string.TTT);
...
}
}
And to call this from your Activity:
NonActivity.doStuff(this);
This will allow you to access your String resource without needing to use a public static field.
for others that find this in the search:
I often get this one when I accidentally call a function using the class name rather than the object name. This typically happens because i give them too similar names : P
ie:
MyClass myclass = new MyClass();
// then later
MyClass.someFunction();
This is obviously a static method. (good for somethings)
But what i really wanted to do (in most cases was)
myclass.someFunction();
It's such a silly mistake, but every couple of months, i waste about 30 mins messing with vars in the "MyClass" definitions to work out what im doing wrong when really, its just a typo.
Funny note: stack overflow highlights the syntax to make the mistake really obvious here.
You can either make your variable non static
public final String TTT = (String) getText(R.string.TTT);
or make the "getText" method static (if at all possible)
getText is a member of the your Activity so it must be called when "this" exists. Your static variable is initialized when your class is loaded before your Activity is created.
Since you want the variable to be initialized from a Resource string then it cannot be static. If you want it to be static you can initialize it with the String value.
You can not make reference to static variable from non-static method.
To understand this , you need to understand the difference between static and non-static.
Static variables are class variables , they belong to class with their only one instance , created at the first only.
Non-static variables are initialized every time you create an object of the class.
Now coming to your question, when you use new() operator we will create copy of every non-static filed for every object, but it is not the case for static fields. That's why it gives compile time error if you are referencing a static variable from non-static method.
This question is not new and existing answers give some good theoretical background. I just want to add a more pragmatic answer.
getText is a method of the Context abstract class and in order to call it, one needs an instance of its subclass (Activity, Service, Application or other). The problem is, that the public static final variables are initialized before any instance of Context is created.
There are several ways to solve this:
Make the variable a member variable (field) of the Activity or other subclass of Context by removing the static modifier and placing it within the class body;
Keep it static and delay the initialization to a later point (e.g. in the onCreate method);
Make it a local variable in the place of actual usage.
Yes u can make call on non-static method into static method because we need to remember first' we can create an object that's class we can call easyly on non -static method into static mathod

Java error when refreshing a Jpanel [duplicate]

Building a multi-language application in Java. Getting an error when inserting String value from R.string resource XML file:
public static final String TTT = (String) getText(R.string.TTT);
This is the error message:
Error: Cannot make a static reference to the non-static method getText(int) from the type
Context
How is this caused and how can I solve it?
Since getText() is non-static you cannot call it from a static method.
To understand why, you have to understand the difference between the two.
Instance (non-static) methods work on objects that are of a particular type (the class). These are created with the new like this:
SomeClass myObject = new SomeClass();
To call an instance method, you call it on the instance (myObject):
myObject.getText(...)
However a static method/field can be called only on the type directly, say like this:
The previous statement is not correct. One can also refer to static fields with an object reference like myObject.staticMethod() but this is discouraged because it does not make it clear that they are class variables.
... = SomeClass.final
And the two cannot work together as they operate on different data spaces (instance data and class data)
Let me try and explain. Consider this class (psuedocode):
class Test {
string somedata = "99";
string getText() { return somedata; }
static string TTT = "0";
}
Now I have the following use case:
Test item1 = new Test();
item1.somedata = "200";
Test item2 = new Test();
Test.TTT = "1";
What are the values?
Well
in item1 TTT = 1 and somedata = 200
in item2 TTT = 1 and somedata = 99
In other words, TTT is a datum that is shared by all the instances of the type. So it make no sense to say
class Test {
string somedata = "99";
string getText() { return somedata; }
static string TTT = getText(); // error there is is no somedata at this point
}
So the question is why is TTT static or why is getText() not static?
Remove the static and it should get past this error - but without understanding what your type does it's only a sticking plaster till the next error. What are the requirements of getText() that require it to be non-static?
There are some good answers already with explanations of why the mixture of the non-static Context method getText() can't be used with your static final String.
A good question to ask is: why do you want to do this? You are attempting to load a String from your strings resource, and populate its value into a public static field. I assume that this is so that some of your other classes can access it? If so, there is no need to do this. Instead pass a Context into your other classes and call context.getText(R.string.TTT) from within them.
public class NonActivity {
public static void doStuff(Context context) {
String TTT = context.getText(R.string.TTT);
...
}
}
And to call this from your Activity:
NonActivity.doStuff(this);
This will allow you to access your String resource without needing to use a public static field.
for others that find this in the search:
I often get this one when I accidentally call a function using the class name rather than the object name. This typically happens because i give them too similar names : P
ie:
MyClass myclass = new MyClass();
// then later
MyClass.someFunction();
This is obviously a static method. (good for somethings)
But what i really wanted to do (in most cases was)
myclass.someFunction();
It's such a silly mistake, but every couple of months, i waste about 30 mins messing with vars in the "MyClass" definitions to work out what im doing wrong when really, its just a typo.
Funny note: stack overflow highlights the syntax to make the mistake really obvious here.
You can either make your variable non static
public final String TTT = (String) getText(R.string.TTT);
or make the "getText" method static (if at all possible)
getText is a member of the your Activity so it must be called when "this" exists. Your static variable is initialized when your class is loaded before your Activity is created.
Since you want the variable to be initialized from a Resource string then it cannot be static. If you want it to be static you can initialize it with the String value.
You can not make reference to static variable from non-static method.
To understand this , you need to understand the difference between static and non-static.
Static variables are class variables , they belong to class with their only one instance , created at the first only.
Non-static variables are initialized every time you create an object of the class.
Now coming to your question, when you use new() operator we will create copy of every non-static filed for every object, but it is not the case for static fields. That's why it gives compile time error if you are referencing a static variable from non-static method.
This question is not new and existing answers give some good theoretical background. I just want to add a more pragmatic answer.
getText is a method of the Context abstract class and in order to call it, one needs an instance of its subclass (Activity, Service, Application or other). The problem is, that the public static final variables are initialized before any instance of Context is created.
There are several ways to solve this:
Make the variable a member variable (field) of the Activity or other subclass of Context by removing the static modifier and placing it within the class body;
Keep it static and delay the initialization to a later point (e.g. in the onCreate method);
Make it a local variable in the place of actual usage.
Yes u can make call on non-static method into static method because we need to remember first' we can create an object that's class we can call easyly on non -static method into static mathod

Hitting a wall in my Java Homework [duplicate]

Building a multi-language application in Java. Getting an error when inserting String value from R.string resource XML file:
public static final String TTT = (String) getText(R.string.TTT);
This is the error message:
Error: Cannot make a static reference to the non-static method getText(int) from the type
Context
How is this caused and how can I solve it?
Since getText() is non-static you cannot call it from a static method.
To understand why, you have to understand the difference between the two.
Instance (non-static) methods work on objects that are of a particular type (the class). These are created with the new like this:
SomeClass myObject = new SomeClass();
To call an instance method, you call it on the instance (myObject):
myObject.getText(...)
However a static method/field can be called only on the type directly, say like this:
The previous statement is not correct. One can also refer to static fields with an object reference like myObject.staticMethod() but this is discouraged because it does not make it clear that they are class variables.
... = SomeClass.final
And the two cannot work together as they operate on different data spaces (instance data and class data)
Let me try and explain. Consider this class (psuedocode):
class Test {
string somedata = "99";
string getText() { return somedata; }
static string TTT = "0";
}
Now I have the following use case:
Test item1 = new Test();
item1.somedata = "200";
Test item2 = new Test();
Test.TTT = "1";
What are the values?
Well
in item1 TTT = 1 and somedata = 200
in item2 TTT = 1 and somedata = 99
In other words, TTT is a datum that is shared by all the instances of the type. So it make no sense to say
class Test {
string somedata = "99";
string getText() { return somedata; }
static string TTT = getText(); // error there is is no somedata at this point
}
So the question is why is TTT static or why is getText() not static?
Remove the static and it should get past this error - but without understanding what your type does it's only a sticking plaster till the next error. What are the requirements of getText() that require it to be non-static?
There are some good answers already with explanations of why the mixture of the non-static Context method getText() can't be used with your static final String.
A good question to ask is: why do you want to do this? You are attempting to load a String from your strings resource, and populate its value into a public static field. I assume that this is so that some of your other classes can access it? If so, there is no need to do this. Instead pass a Context into your other classes and call context.getText(R.string.TTT) from within them.
public class NonActivity {
public static void doStuff(Context context) {
String TTT = context.getText(R.string.TTT);
...
}
}
And to call this from your Activity:
NonActivity.doStuff(this);
This will allow you to access your String resource without needing to use a public static field.
for others that find this in the search:
I often get this one when I accidentally call a function using the class name rather than the object name. This typically happens because i give them too similar names : P
ie:
MyClass myclass = new MyClass();
// then later
MyClass.someFunction();
This is obviously a static method. (good for somethings)
But what i really wanted to do (in most cases was)
myclass.someFunction();
It's such a silly mistake, but every couple of months, i waste about 30 mins messing with vars in the "MyClass" definitions to work out what im doing wrong when really, its just a typo.
Funny note: stack overflow highlights the syntax to make the mistake really obvious here.
You can either make your variable non static
public final String TTT = (String) getText(R.string.TTT);
or make the "getText" method static (if at all possible)
getText is a member of the your Activity so it must be called when "this" exists. Your static variable is initialized when your class is loaded before your Activity is created.
Since you want the variable to be initialized from a Resource string then it cannot be static. If you want it to be static you can initialize it with the String value.
You can not make reference to static variable from non-static method.
To understand this , you need to understand the difference between static and non-static.
Static variables are class variables , they belong to class with their only one instance , created at the first only.
Non-static variables are initialized every time you create an object of the class.
Now coming to your question, when you use new() operator we will create copy of every non-static filed for every object, but it is not the case for static fields. That's why it gives compile time error if you are referencing a static variable from non-static method.
This question is not new and existing answers give some good theoretical background. I just want to add a more pragmatic answer.
getText is a method of the Context abstract class and in order to call it, one needs an instance of its subclass (Activity, Service, Application or other). The problem is, that the public static final variables are initialized before any instance of Context is created.
There are several ways to solve this:
Make the variable a member variable (field) of the Activity or other subclass of Context by removing the static modifier and placing it within the class body;
Keep it static and delay the initialization to a later point (e.g. in the onCreate method);
Make it a local variable in the place of actual usage.
Yes u can make call on non-static method into static method because we need to remember first' we can create an object that's class we can call easyly on non -static method into static mathod

Calculate total calls made to a method without using static

UPDATE:: OK i am putting the original problem statement here
Given the Main class create a method createPerson and call it in any other method more than once, then on the basis of the number of times the createPerson has been executed you have to initialize the objects and input names of students and output the names.
once i come to know how many objects i have to create its quite trivial to program the later part
for the prior problem of finding the number of objects to be created i have chosen the way of file handling as i come from a C, C++ background where file handling is comparatively simple.
now how should i modify the program such that i write an integer in the file, and later when i will read the file i will get the number of objects
this example forbids the use of static variable, it is a sort of brain teaser
so do Not use static
this is my Main.java file
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
int i;
Student[] totalStudents = new Student[10];
Student.create3Persons();
Student.create2Persons();
}
}
and this is my Student.java file
import java.io.*;
public class Student {
private static void createPerson() throws IOException{
int number=0;
File file = new File("arg.txt", null);
FileOutputStream fos = new FileOutputStream(file);
DataOutputStream dos = new DataOutputStream(fos);
FileInputStream fis = new FileInputStream(file);
DataInputStream dis = new DataInputStream(fis);
while(dis.readInt()!= -1)
{
number++;
dos.writeInt(1);
}
}
static void create2Persons() throws IOException{
Student.createPerson();
Student.createPerson();
}
static void create3Persons() throws IOException{
Student.createPerson();
Student.createPerson();
Student.createPerson();
}
}
How should i modify this program so that i calculate how many times has been the function createPerson being called??
If you want to calculate how many times a static method has been called, you have to use a static variable - it's genuinely global state. EDIT: Yes, you can use the file system as another repository for global state, but I'd personally say that's generally a bad idea - particularly if it's just to get round a requirement in an academic question.
I guess there are some exceptions to this - if the static method is provably only called from one class, and that class is a singleton, then there could be an instance method in that singleton... but that's pretty much a corner case. In your case, create3Persons and create2Persons are both accessible from anywhere in the package, and they aren't instance methods in a singleton, so therefore there's no single context in which to keep the call count except a static variable.
Perhaps if you could explain a bit more about what you're trying to achieve, we could help you more...
EDIT: Yes, if you can rely on cooperative callers - and you can change the method signatures - then you could keep (say) an AtomicInteger, and make sure you always pass a reference to the same object into the createStudent method. Again, we'd really need to know what the rules of the question are...
i have to disagree with #Jon Skeet, i dont think you have to use a static variable. Why not simply return the number of items created, and keep the total count in a local variable in your main method ? (assuming youre allowed to modifiy method signatures of course, otherwise youre stuck with the global variable solution) you seem to have an unused counter right there already, why not use it?
You can use:
synchronized(this){
System.setProperty("methodCounter",number++);
}
instead of a file based counter. And in the main method:
System.getProperty("methodCounter");
Use AOP (Aspect-Oriented Programming).
You can use a system property to store the quantity of calls...this way you don't have to use the file system or AOP or change method signature.
Mostly when we want to retain value across method, either we go for
Static variable
or pass the variable as reference
or pass the variable and return the updated variable and use it again
int createPerson(int counter);
i got the Solution
instead of file handling i am doing this
static int createPerson(int c){
return (++c);
}
static int create2Persons(int c) {
return Student.createPerson(Student.createPerson(c));
}
static int create3Persons(int c) {
return Student.createPerson(Student.createPerson(Student.createPerson(c)));
}
public static int create5Persons(int i) {
return Student.createPerson(Student.createPerson(Student.createPerson(Student.createPerson(Student.createPerson(i)))));
}
and in the main method i have initialised an integer and i do this
c += Student.create2Persons(i)-1;
c += Student.create3Persons(i)-1;
c += Student.create5Persons(i)-1;
System.out.println(c+"c is");
this saves use of files
how to tag the thread as answered?

Reflection in java?

I am newbie to java programming language.
My problem is:
I want to read sys.input for a class name from console. Upon reading the name of the class, I want to generate that class automatically and call its method if that class exists already.
my trial is here. Although I dont get any error, nothing happens.
my kind regards.
class s1{
public s1(){
System.out.println(""+ s1.class);
}
}
public class reflection {
public static void main(String[] args) throws IOException, ClassNotFoundException{
System.out.println("enter the class name : ");
BufferedReader reader= new BufferedReader(new InputStreamReader(System.in));
String line = "reflection_N3.";
line+=reader.readLine();
//System.out.println(line);
// "name" is the class name to load
Class clas = Class.forName(line);
clas.getClassLoader();
}
}
You are not creating an instance of the class. Try
Class clas = Class.forName(line);
Object obj = clas.newInstance();
However, the problem is, you can't do much with this object unless you know its exact type, and cast it to that type.
In this example, you could try casting it to your class type, e.g.
if (obj instanceof s1) {
s1 myS1 = (s1) obj;
myS1.s1();
}
However, this hardly works in real life, where you don't know the possible types in advance. The typical solution to this is to define an interface for a specific purpose, and require that the class implements that interface. Then you can downcast the class instance to that interface (throwing an exception if the cast fails), and call its interface methods, without needing to know its concrete type.
Or, as #helios noted, you can use reflection to obtain a method of the loaded class having a specific name.
Btw the Java convention is to start class names with uppercase, hence S1 and Reflection.
You're only obtaining the ClassLoader, you're never actually constructing an object of the specified class.
Use clas.newInstance() if you want to call the default constructor, or investigate Class.getConstructor(...) if you need to call a specific constructor.

Categories