I need a way to check if a boolean value of another object is true, and only in that case should do something.
So, I have 2 classes:
public class A{
private boolean test = false;
...
...
public boolean returnTest(){ return test; }
}
public class B{
private boolean abcd;
public B(A myA){
this.abcd = myA.returnTest();
}
public void test(){
while(!abcd){
// wait
}
// do something
}
}
The problem is that it remain in the while loop forever even if the test value of the object A become true. Why ?
In your case, pass instance to function test() is better, invoke test() with passing instance of A. Everytime an new instance of A is created or an existing instance has updated its attributes, pass it to test()
public void test(A a){
while(!a.returnTest()){
// wait
}
}
There is no real alternative to changing test() to do while (!myA.returnTest()). If you store a result in a variable it will stay permanently. (Properties of objects, or method calls, can reflect changes elsewhere, but variables themselves cannot.)
Booleans are immutable so you cannot make a copy of a reference to them.
Instead, try:
public class B{
private A a;
public B(A myA){
this.a= myA();
}
public void test(){
while(!myA.returnTest()){
// wait
}
// do something
}
}
In Java 8 you can use a method reference.
public class A{
private boolean test = false;
...
...
public boolean returnTest(){ return test; }
}
public class B{
private BooleanSupplier abcd;
public B(A myA){
this.abcd = myA::returnTest; // a reference to this method.
}
public void test(){
while(!abcd.getAsBoolean()) { // calls the method each time.
// wait
}
// do something
}
}
If you must do so, one option is to use a java.util.concurrent.atomic.AtomicBoolean, which is mutable type. You can retrieve and update values using get() and set(boolean) respectively. This can also be a good option if thread-safety can potentially be a concern in your application.
Otherwise you have to store a reference to the A instance and use the flag inside it instead of checking a different variable.
Related
I have class which has static block as follows:
public class DataProvider {
static int a;
static String b;
static {
a = readRollConfiguration();
b = readNameConfiguration();
}
public static int getRoll() {
return a;
}
}
I change configuration and call methods of this class then i get older values of a and b, until app is killed and restart.
So is there any way to call static block so that a and b get updated?
a and b are just loaded once. If you want to call the methods readRollConfiguration and readNameConfiguration every time you call the method getRoll, you have to call that method there.
public class DataProvider {
public static int getRoll() {
return readRollConfiguration();
}
}
You can use Class.forName("com.the.ClassName"); to call static block without ceating any instance of that class.
You are initializing the values of static variables a and b as part of DataProvider class initialization using a static initializer block and these values will be same unless you change the static values again.
So, update your DataProvider class and add reloadRollConfig() and reloadNameConfig() as shown below for reloading the values again from configurations:
public class DataProvider {
static int a;
static String b;
static {
a = readRollConfiguration();
b = readNameConfiguration();
}
public static int getRollConfig() {//no reload, gets the current value
return a;
}
public static int getNameConfig() {//no reload, gets the current value
return b;
}
public static int reloadAndGetRollConfig() {//reload and get the new value
a = readRollConfiguration();
return a;
}
public static int reloadAndGetNameConfig() {//reload and get the new value
b = readNameConfiguration();
return b;
}
}
Yes, I know its bad idea, but configuration changes not very often.
I strongly suggest you reload the values of a and b periodically to set the latest values to the DataProvider class. You can do this by using a simple scheduler or implement a caching layer using frameworks like Ehcache. Caching frameworks provide many features for caching the static data and I suggest you need to consider implementing caching for this kind of configuration data (i.e., the data which does not change very often).
You can't call static block. It is called when Class object is created. You can think of it as constructor of Class object that describes your class. Unlike constructor which is called when instance is created.
The way you have done is completely wrong. static block will run only once whenever your class is loaded.
public class DataProvider {
static int a;
static String b;
static {
a = getSum();
b = "15";
}
public static int getSum(){
return 5 + 6;
}
public static int getRoll() {
return a;
}
}
So in this piece of code variable a will be created and assigned value 11 whenever DataProvider class is loaded. And, the point is that this value will be same until unless DataProvider class will not be recompiled or reloaded. Even, if the getSum() return new value each time, variable a gonna contain first value only.
So if you want a to be dynamic you have update variable every time you want to access a like this:
public static int get_a() {
return a = getSum();
}
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)
This is for a personal project. Not assignment or work.
Say I have an object, objA that has a function callB().
When I run callB() it calls a function in object B. The function in objB can have calls to functions in objA.
Eg. objA calls callB().
Inside callB() there is a function like setObjAName() which sets a variable on objA.
How would I do this in Java? How do I reference objA from objB?
The simplest method is to simply pass a reference to A in with the method call, which will allow for B to access any of A's public methods.
public class ClassA {
public String someAVar;
public void callB(ClassA a){
//do stuff
ClassB b = new ClassB();
b.setObjA(this,"newValue");
}
}
public class ClassB{
public void setObjA(ClassA A, String newValue){
A.someAVar = newValue;
}
}
Alternatively you might want the variable to be settable without passing in a particular instance, in which case static methods and variables are your friend.
public class ClassA {
public static String someAVar;
public void callB(){
//do stuff
ClassB b = new ClassB();
b.setObjA("newValue");
}
}
public class ClassB{
public void setObjA(String newValue){
ClassA.someAVar = newValue;
}
}
I have a Singleton class to save the state of an application's module.
This class simply have a lot of class variables with setters and getters :
public class ModuleState{
private static ModuleState instance;
private A a;
private B b;
private C c;
..
..
..
..
private ModuleState (){}
public ModuleState getInstance(){
if(instance==null)
instance=new ModuleState();
return instance;
}
}
At a precise moment of the application lifecycle, i have the need to CLEAR the module's state. What i do now is to reset ALL the variables in ModuleState by a clearAll() method like this:
public void clearAll(){
a=null;
b=null;
c=null;
..
..
}
My question is the following : there is a cleaner method to do this reset? Possibly clearing the singleton instance itself, without resetting every class variable?
The problem with this approach is that i may have the need to add a new class variable to the ModuleState. In this case i must remember to add a line in the clearAll() method to reset the new variable.
What about ...
public static volatile ModuleState instance = null;
public static void reset() {
instance = new ModuleState();
}
p.s.: as per discussion below: in a multithreaded environment it's very important to synchronize the access on the instance because the JVM is allowed to cache its value. You can use volatile as shown above. Thanks to all!
Cheers!
no, this approach is perfectly acceptable. you are of course synchronizing access to these state objects in some way, right? otherwise you risk someone seeing a half-cleared config object.
another thing you could do to future-proof yourself against any extra state added in the future is store all of your state in a HashMap, for example, instead of individual fields. this way, clear()ing the hashmap ensures that all state is wiped and adding any extra state in the future becomes safer
You need to maintain the same object instance, in order to comply with the Singleton pattern, so your approach makes sense: altering the members.
However, if you wanted to clean it up a little bit, why not just have an internal list, like:
ArrayList<Object> members = new ArrayList<Object>();
// If it actually is Object, there's no need to paramaterize.
// If you want, you can actually make the members implement a common interface,
// and parameterize the ArrayList to that.
Another Option would be to have a HashMap, that binds the key word to the member.
HashMap<String,Object> members = new HashMap<String,Object>();
// Again, same parameterization rules apply.
For an ArrayList or a HashMap, the clearAll method might look like this:
public class ModuleState()
{
public void clearAll()
{
members.clear();
}
}
This method won't need to change.
May be this can help you:
public class SingletonBean {
private static SingletonBean instance = new SingletonBean();
private static Object privateMutex = new Object();
private SingletonBean() {
//to prevent instantiation
}
public class ObjectsContainer {
private Object A;
private Object B;
private Object C;
public Object getA() {
return A;
}
public void setA(Object a) {
A = a;
}
public Object getB() {
return B;
}
public void setB(Object b) {
B = b;
}
public Object getC() {
return C;
}
public void setC(Object c) {
C = c;
}
}
private ObjectsContainer objectsContainer;
private void resetObjectsContainer() {
objectsContainer = new ObjectsContainer();
}
public static SingletonBean getInstance() {
return SingletonBean.instance;
}
public static void clearAll() {
synchronized (privateMutex) {
SingletonBean.getInstance().resetObjectsContainer();
}
}
public static ObjectsContainer getObjectsContainer() {
synchronized (privateMutex) {
return instance.objectsContainer;
}
}
}
public class SomeClass {
public void someMethod() {
SingletonBean.getObjectsContainer().getA();
}
}
Make an inner class to hold the fields, then replace that instance when you want to reset. The write to the field would make the change to all three fields essentially atomic.
public class ModuleState {
private static volatile ModuleState instance;
private static class Values {
A a;
B b;
C c;
}
private volatile Values values = new Values()(
private ModuleState (){}
public ModuleState getInstance(){
if (instance==null) {
synchronized (ModuleState.class) {
if (instance==null) {
instance = new ModuleState();
}
}
}
return instance;
}
public synchronized A getA() {
return values.a;
}
public synchronized void reset() {
values = new Values();
}
By the way, your null checking initialization code was not threadsafe. I fixed that too.
Note that to make this work, you must make the reference to values volatile and synchronize all access to it, otherwise (due to the java memory model) other threads than the one that calls reset() may see the old reference.
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.