Reset mutable class fields - java

Say I have a class with some mutable fields:
public class Test
{
private boolean isCorrect;
private String userId;
public void run() {...}
// more methods
}
The run() method will be modifying these fields. My issues is that the caller of this class might call run() any number of times, and for this reason I should be re-setting the fields back to null.
My question is, what is the best practice for this scenario? Should I reset the fields every time the method is called?
public void run()
{
isCorrect = null;
userId = null;
// do stuff
}
Or is there a cleaner/smarter approach to this?

The simple answer is use local variables. The OP has clarified in the comments that run calls other methods on the same instance that expect to use these variable too.
The class should be split. The run method should create an object containing the fields and call methods on that.
public class Test {
public void run() {
TestImpl impl = new TestImpl();
impl.run();
}
// more methods
}
class TestImpl {
private boolean isCorrect;
private String userId;
public void run() {...}
// more methods
}
You could make the new class a nested class, though that does cause excessive indention. An inner class would also have direct access to any longer lived variables of Test. An anonymous inner class (or, more obscurely, a local class) would be even more convenient but indented.

I would do it this way. Using an exception. So anyone who dares to use run() twice gets kicked out.
package test;
import com.sun.jdi.IncompatibleThreadStateException;
public class Test{
private boolean isRunning = false;
public void run() throws IncompatibleThreadStateException{
if(this.isRunning) {
throw new IncompatibleThreadStateException();
}
else {
this.isRunning = true;
}
}
public static void main(String[] args) {
}
}

Related

Thread safe access to private field

So I have the following scenario (can't share the actual code, but it would be something like this):
public class Test
{
private Object obj;
public void init()
{
service.registerListener(new InnerTest());
}
public void readObj()
{
// read obj here
}
private class InnerTest implements Listener
{
public synchronized void updateObj()
{
Test.this.obj = new Object();
// change the obj
}
}
}
The InnerTest class is registered as listener in a service. That Service is running in one thread the calls to readObj() are made from a different thread, hence my question, to ensure consistency of the obj is it enough to make the UpdateObj() method synchronized?
I would suggest using another object as a lock to ensure that the class only blocks when the obj is accessed:
public class Test
{
private final Object lock = new Object();
private Object obj;
public void init()
{
service.registerListener(new InnerTest());
}
public void readObj()
{
synchronized(lock){
// read obj here
}
}
private class InnerTest implements Listener
{
public void updateObj()
{
synchronized(Test.this.lock){
Test.this.obj = new Object();
// change the obj
}
}
}
}
Then use that lock in all methods that need to have consistent access to obj. In your current example the readObj and updateObj methods.
Also as stated in the comments, using synchronized on the method level in your InnerTest class, will not really work as you probably intended. That is, because synchronized methods will use a synchronized block on the this variable. Which just blocks your InnerTest class. But not the outer Test class.

How to Transfer values to another class method

I have global variables in Question class and increments these values in event handler. I have another class User which contains a static method Details(). I want to pass these two variables values (after increments) from event handler to the Details() of the User class.:
public class Question {
public int phCounter = 0;
public int chemCounter = 0;
private void CategoryCbActionPerformed(java.awt.event.ActionEvent evt) {
phCounter++;
chemCounter++;
}
}
...
public class User {
static void Details() {
public counter ;
}
}
My question is is there any way, except to send values as arguments to Details(), in which I can inject these incremented values inside Details() method.
First off: Method names in Java are camelCase. Not UpperCase ;)
If you want to access fields of a class in another class there are serveral ways to achieve that. The easiest one are static fields:
public class MyClass {
public static String accessible;
}
public class AnotherClass {
public void someMethod() {
// You can set the value ...
MyClass.accessible = "New value";
}
public void anotherMethod() {
// ... and get the value.
System.out.println(MyClass.accessible);
}
}
But remember: The value of a static field will be always the same unless you change it, even when you create new instances of the class where the static field is used. You should avoid static fields if possible. In most cases you can take the OOP way to achieve the same result.
~ Morph
I can inject these incremented values inside Details() method.
what does this statement mean?
your code below can not be compiled!
public class User{
static void Details()
{
public counter;
}
}
if you want to use reflection to send args to method ,why not just call User.Details(int a,int b)

Java reflection, add volatile modifier to private static field

It's possible to add the volatile modifier to a field that is private and static?
Example Code
// I don't know when test is initalized
public class Test {
private static String secretString;
public Test() {
secretString = "random";
}
}
public class ReflectionTest extends Thread {
public void run() {
Class<?> testClass = Class.forName("Test");
Field testField = testClass.getDeclaredField("secretString");
while (testField.get(null) == null) {
// Sleep, i don't know when test is initalized
// When it'is i need the String value
// But this loop never end.
}
}
}
I think that if i set the field volatile the loop end
without any problem
If you don't have access to the class, you cannot modify it.
Instead, find the code that instantiates it, and add a synchronized block around it:
synchronized(Test.class) {
new Test();
}
Now, in your thread code, do:
while(true) {
synchronized(Test.class) {
if(testField.get(null) == null) break;
}
// ... whatever
}
May I ask why you need this? If a field is made private, there is usually a reason for it. You are circumventing the class creator's intent with your use of reflection ...
Also, initializing static fields in an instance constructor seems ... fishy :-/

How can I access a method of an "unnamed" class?

public class Test {
public static void main(String[] args) {
DemoAbstractClass abstractClass = new DemoAbstractClass() {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
};
abstractClass.runner();
/**
* I want to access getVal method here
*/
}
}
abstract class DemoAbstractClass {
public void run() {
System.out.println("running");
}
public abstract void runner();
}
Here, I'm declaring an abstract class DemoAbstractClass. I can obviously create a new class that extends this class and add this method to it. But, I would prefer not doing that in my scenario.
Is there any other way to access getVal method in above code??
You can't. You need to make a proper (non-anomous) class out of it. Make it an inner private class if you want to limit its scope.
Alternatively, you could use a StringBuffer and share a referense to it between the methods. Not extremely clean however.
Related question:
Accessing inner anonymous class members
Short of using reflection, you cannot as you have no access to the concrete type of the object to be able to bind the methodcall to
If you don want to do something like this in a sane manner, declare a named class and use that as the type of abstractClass
Unfortunately, if you cannot name the type, you cannot access the methods at the language level.
What you can do, though, is use the reflection API to get a Method object and invoke it on this object.
This, however, is pretty slow. A private class or private interface would be much faster.
I can obviously create a new class that extends this class and add this method to it.
You've already done this; the end result was an anonymous inner class: new DemoAbstractClass() { ... }; If you just moved that declaration into its own class -- you can even make it a private class -- you can access getVal.
Per your example above:
public class Test {
public static void main(String[] args) {
DemoClass abstractClass = new DemoClass();
abstractClass.runner();
/**
* I want to access getVal method here
*/
abstractClass.getVal(); // can do this here now
}
private class DemoClass extends DemoAbstractClass {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
}
}
}
Another option is to make a StringBuilder a member of the main method and use the closure nature of anonymous inner methods:
public static void main(String[] args) {
final StringBuilder value = new StringBuilder();
DemoAbstractClass abstractClass = new DemoAbstractClass() {
#Override
public void runner() {
value.append( "test" );
System.out.println(val);
this.run();
}
};
abstractClass.runner();
// use val here...
String val = value.toString();
}

Reusing class after calling static methods

Suppose I have a class with several static void methods, for example:
class MyClass {
public static void doJob() {
// ...
}
public static void doSmthElse() {
// ...
}
}
how can I modify it to call my static methods like this:
MyClass.doJob().doSmthElse().doJob();
instead of
MyClass.doJob();
MyClass.doSmthElse();
MyClass.doJob();
I know how to do it with non-static methods (just return this), but how to do it with static fields?
Well, you could do this:
// Horrible, don't do it!
class MyClass {
public static MyClass doJob() {
// ...
return null;
}
public static MyClass doSmthElse() {
// ...
return null;
}
}
At that point your code will compile, as Java allows access to static methods "via" references. The fact that you're returning null is irrelevant, because the compiler will only look at the compile-time type of the expression MyClass.doJob() in order to work out which doSmthElse() method to call; the static method will then be called without examining the return value at all.
But please don't do this - it's a really nasty code smell, as your code looks like it's doing one thing when it's actually doing another.
Options:
Just live with your more verbose calls
Extract the static methods into a class where it makes sense for them to be instance methods (this may well improve testability etc as well)
Import the methods statically
Create a larger method in MyClass which calls the three methods one after another.
You can make this class singleton and do
return getInstance();
in every method
You can create a dummy instance of you class and return this. You will use static members of class, but return a reference to regular instance (just for fun, just for code style). But I wouldn't like to use this approach.
class MyClass {
private static int data = 0;
private static MyClass link = null;
public static void doJob() {
// do job with static data such as "data"
return checkMe();
}
public static void doSmthElse() {
// do someting else with static data such as "data"
return checkMe();
}
private MyClass static void checkMe() {
if (link == null) link = new MyClass();
return link;
}
}
It is immpossible because there is no object you can return.

Categories