I want to keep track of values of an instance variable, and my breakpoint starts at a static method. I can't check the instance variable value. Is there a way to do that? I searched over google, but found no clue.
Is it because instance can't be accessed in a static method?
You could pass the variable that you are tracking into the method. Although you just make a note every time you do this so you can remove it when you are done testing.
But honestly, if you don't have access to the variable from within the method, then it probably won't change by the time you have exited the method, unless you have multiple threads. Therefore, you can set the breakpoint after/before the method is called.
A static method cannot access the value of an instance variable, which, by definition, is undefined until an instance of the object is created.
public class A {
private int b;
public static void foo() {
b = 1;
}
}
Will not compile for this very reason. A work around it to make b itself static. Of course, you should understand what making b static means. It means that there is exactly one instance of b no matter how many instances of the class exist within a given JVM.
Related
public class Main {
void sum(int a, int b) {
int c = a + b;
System.out.println(c);
}
public static void main(String args[]) {
Main ob = new Main();
ob.sum(10, 125);
}
}
In the above code there is no instance variable, but I have read that if a method is an instance method it should access instance variable. So is 'sum' an instance method?
sum is an instance method here, because it's not static and requires an instance of the object. You create your instance here:
Main ob = new Main();
In this particular case sum could indeed be made static, slightly simplifying the code by not requiring an instance.
I have read that if a method is an instance method it should access instance variable
I suspect what you were reading is suggesting that if a method doesn't interact with the instance at all then it probably should be static. There may be mention of the term "pure function" in the text somewhere.
I wouldn't go so far as to say that all potentially static methods everywhere should be made static as a universal rule. It really comes down to the semantics of the object itself. Since the object you have here has very little semantic context, this one tiny example could easily go either way.
But suppose you expanded your object to also include methods for subtract, multiply, divide, etc. As the object expands, suppose one or more of those additional methods did use instance variables. It would be a jarring experience to have an object with multiple semantically-similar methods, some of which are static and some of which are not.
Rather than focus on any particular rule that someone gives you, focus on what you are intending to build as your object. If you think that it should be static, make it as such. If you feel that it shouldn't, then don't. If you're unsure, then as an exercise implement both and see which you prefer in that particular case.
Looking to the future plans for what you're intending to build is important, because the more code you have relying on your object throughout the application the harder it will be to change from static to instance or vice-versa.
Yes, 'sum' an instance method because any non-static method is an instance method.
Moreover, It is not necessary that an instance method should access instance variable.
The correct statement is "if a method is an instance method it can access instance variable.
If we define a variable as constant variable, when we use this variable in methods do we have to put method as static ?
static final int AGE=35;
private int daysOfLife(){
return AGE*365;
}
can we define method as like this ?
Even though it is not giving me any errors but is it a good practice to read static data from instance methods?
You shouldn't be only worried about variable / method being static or non - static but about other things too.
I would categorize your actions as - READ & WRITE and here you are trying to READ a default scoped , final & static variable in an INSTANCE , private method.
Concept of statics exits to logically group variables and methods so if your method has only that line and there isn't going to be anything else in that method, I would suggest to keep that grouping consistent and make either that variable an instance variable ( which doesn't make sense if variable is constant among all objects ) and change its scope to private ( if you don't wish variable to be available in same package classes ) OR mark that method as static.
Reading a final & static variable in an instance method is perfectly OK even though writing is questionable ( though final can't be written to but in case variable is not final ) .
Making that variable an instance one is favored if that variable is not going to be accessed by class name somewhere else and then if its going to be class level constant , make it static and change method to be static ( Initializing same constant field in every object will unnecessary cost you memory ) .
As much as i know ....
The 'static' means it is used in a class scope. Meaning it can be used in the entire program. So technically they can be stored in a non-static method, but they'll still be able to be used outside of that instance.
1) there is no need to put method as static because static means it's for class when ever class start running static will run so static block is the thing will run first and only initialize once that's why it's not showing error in compile time
2) other way around we can't put initialize or use non static variable inside static block because static block will run before instance variable so compile time will catch the error
3) Variables that are declared final and are mutable can still be change in some ways; however, the variable can never point at a different object at any time .
4) so there nothing to worry about making method static
I have my main class from which i call my sub class.
My sub class contains some public static variables like
public class SubClass2 extends Main {
public static long a = 0;
public static long b = 0;
public static long c= 0;
public void Analyze(int number)
{
b=2;
//some code
}
}
Where as in main i call the object of the SubClass2.I want everytime when i make the new object of the subclass2 in main then it initializes
all the variables =0 but when i take the print statement of the variable b.It prints out like 4.It adds up the previous value with the new value.
Your fields should not be declared as static in that case. This is why they're not being initialised each time. A static field is initialised once only, then shared by every instance of the class, and depending on accessibility, also outside of the class.
The logic that led to the value 4 must be in the code you've replaced with //some code, but this ins't really relevant here.
If for whatever reason these really should be static fields that are initialised each time an instance is instantiated, then you would have to initialise them manually in the class's constructor. But I'd seriously question the design that leads to this situation...
You are using static variables. These have no connection to any objects you create. They are just global, unique variables. You must erase static. By the way, it is redundant to initialize a field to 0. It is already initialized to zero.
If you use the word static there will only ever be one instance of the variable that is shared between everything created that uses it. Remove static and there will be a new, but more importantly, individual variable for each time its initialised in a method.
Perhaps better wording is that instance methods can and will access shared/static variables!
Your question embodies a contradiction in terms. Static variables are initialized once, when the class is loaded. If you want variables initialized per-instance, use per-instance (non-static) variables.
I have a method that uses a SwingWorker. Part of the code is shown below:
public class mySocket {
public void writePacket(final String packet) {
// schedules execution on the single thread of the executor (so only one
// background operation can happen at once)
//
executor.execute(new SwingWorker<String, Void>() {
#Override
protected String doInBackground() throws Exception {
// called on a background thread
System.out.println("writing out this packet->" + packet + "
<-");
out.println(packet);
String thePacket = readPacket();
return thePacket;
}
..................
My questions are about the signature of the writePacket method. The variable packet must be declared final or the compiler complains because SwingWorker is an inner class. This raises the following questions about how and when I can assign values to this variable:
Final to me means that the variable can only be assigned a value once. But because the declaration is part of the signature of a method, I don't know what this means in this context.
I always assumed that final variables were assigned values when the class was instantiated but here it is assigned when the method is called. Does the variable passed to the method also need to be declared final and assigned in the class's constructor for this to work?
Can I call the method more than once with different values for packet or because the variable is declared final, does this mean that if I want to call the method with different values, I need to reinstantiate the class for each new value of the variable packet ?
Thanks in advance for your help.
Elliott
1. Final to me means that the variable can only be assigned a value once. But because the declaration is part of the signature of a method, I don't know what this means in this context.
It just means that you can't reassign a new value to the variable packet.
2. I always assumed that final variables were assigned values when the class was instantiated but here it is assigned when the method is called. Does the variable passed to the method also need to be declared final and assigned in the class's constructor for this to work?
You can have local final variables as well. Same rules applies, but they are unrelated to constructor / this reference.
3. Can I call the method more than once with different values for packet or because the variable is declared final, does this mean that if I want to call the method with different values, I need to reinstantiate the class for each new value of the variable packet ?
You can call the method several times with different values. The packet variable is like a local variable. and No, you don't need to reinstantiate the class for each value / call.
Further SO reading:
Cannot refer to a non-final variable inside an inner class defined in a different method
Cannot refer/modify non-final variable in an innerclass
access to variable within inner class in java
The inner class can only reference final variables because the variable that is wantd is actually passed to the inner class ctor as a parameter. If the variable was not final, and changed after the inner class was created, it would no longer be holding onto the current but previous variable. To avoid such strangeness and to keep things simple, variables/parameters must be final for an inner class to read.
Final to me means that the variable can only be assigned a value
once. But because the declaration is part of the signature of a
method, I don't know what this means in this context.
It means the same thing, you can't re-assign the variable.
// this compiles
public void foo(String bar){
bar = "xyz";
}
// this doesn't
public void foo(final String bar){
bar = "xyz";
}
I always assumed that final variables were assigned values when
the class was instantiated but here it is assigned when the method is called.
No, local variables can also be final, and parameters too. They are assigned once per scope (block or method level).
Does the variable passed to the method also need to be
declared final and assigned in the class's constructor for this to
work?
No, that's totally irrelevant
Can I call the method more than once with different values for packet
or because the variable is declared final, does this mean that if I
want to call the method with different values, I need to reinstantiate
the class for each new value of the variable packet ?
No, see above. It's a new variable for each method call.
Final to me means that the variable can only be assigned a value once. But because the declaration is part of the signature of a method, I don't know what this means in this context.
Same thing. It means you cannot re-assign a new value to the local variable that contains the parameter (that is considered bad practice anyway).
I always assumed that final variables were assigned values when the class was instantiated but here it is assigned when the method is called
That first part is true for final instance variables, not for local variables.
But the idea is the same: They need to be assigned a value and it can happen only once.
Can I call the method more than once with different values for packet or because the variable is declared final, does this mean that if I want to call the method with different values, I need to reinstantiate the class for each new value of the variable packet ?
You can call it many times. The parameter being declared final has no impact to code calling of the method (just for its implementation).
I ran across a class that was set up like this:
public class MyClass {
private static boolean started = false;
private MyClass(){
}
public static void doSomething(){
if(started){
return;
}
started = true;
//code below that is only supposed to run
//run if not started
}
}
My understanding with static methods is that you should not use class variables in them unless they are constant, and do not change. Instead you should use parameters. My question is why is this not breaking when called multiple times by doing MyClass.doSomething(). It seems to me like it should not work but does. It will only go pass the if statement once.
So could anyone explain to me why this does not break?
The method doSomething() and the variable started are both static, so there is only one copy of the variable and it is accessible from doSomething(). The first time doSomething() is called, started is false, so it sets started to true and then does... well, something. The second and subsequent times it's called, started is true, so it returns without doing anything.
There's no reason why using a static variable wouldn't work. I'm not saying it's particularly good practice, but it will work.
What should happen is:
The first call is made. The class is initialised, started is false.
doSomething is called. The if fails and the code bypasses it. started is set to true and the other code runs.
doSomething is called again. The if passes and execution stops.
The one thing to note is that there is no synchronization here, so if doSomething() was called on separate threads incredibly close together, each thread could read started as false, bypass the if statement and do the work i.e. there is a race condition.
The code given is not thread safe. The easy way to make this code thread safe would be to do something like
public class MyClass {
private static AtomicBoolean started = new AtomicBoolean(false);
private MyClass(){
}
public static void doSomething(){
boolean oldValue = started.getAndSet(true);
if (oldValue)
return;
}
//code below that is only supposed to run
//run if not started
}
}
This should be thread safe as the AtomicBoolean getAndSet is synchronized.
Admittedly this is not an issue if you do not use threads (please note that a webapp can use quite a lot of threads handling various requests without you being aware of that).
It's not particularly nice code - generally designs should use object instances where state changes, but there's nothing illegal with it.
My understanding with static methods is that you should not use class variables in them unless they are constant, and do not change.
You seem to have extrapolated from a design guideline to a language feature. Read one of the many Java tutorials available on line as to what is actually allowed in the language. You can use non-final static fields freely in static methods, but it leads to procedural rather than object-oriented code.
Instead you should use parameters.
It's hard to see how an started parameter would be used - if the caller knew that the process has been started, why would they call the method?
Within static method, you are allowed to invoke or access static members within the same class.
Disregarding multiple threads scenarios,
The first call to doSomething will make the boolean static variable to true, therefore, the second call will execute the code of if block which just simply exit the method.
You static method is talking to a static class variable, so it should be fine. You could think of this as global code and a global variable, tho it IS in the namespace of the class.
If you tried to access a non-static member variable:
private int foo = 0;
from within the static method, the compiler will and should complain.
started is false - initial state.
MyClass.doSomething() - statered is now true
MyClass.doSomething() - started is STILL true
MyClass foo = new MyClass();
foo.started -> it's STILL true, because it's static
foo.doSomething() - not sure you can do this in Java, but if you can, it's be STILL TRUE!
Now, there are issues in the above code with thread safety, but aside from that, it appears to be working as designed.
Just remember the thumb rule that "Static variables are class-level variables and all non-static variables are instance variables". Then you won't have any confusion at all!
i.e.
For static variable, All references made in code to the variable point to same memory location. And for non-static variable, new memory allocation is done whenever new instance of that class is created (so every reference made in code to the variable points to a different memory location allocated for calling class instance).
The code above works completely well (unless it runs in a multithreaded environment). Why do you think it should break?
My understanding with static methods is that you should not use class variables in them unless they are constant, and do not change
I guess only static members can be accessed. It need not be constant!
My question is why is this not breaking when called multiple times by doing MyClass.doSomething(). It seems to me like it should not work but does. It will only go pass the if statement once
Per the existing logic. Only the first call runs the //code to be run part