I am developing a Java Program, I have 2 different classes that need to share variables with each other. So for this purpose I created a third class, which contains these shared variables. Basically, first class has its own flag in this third class, and second class has its own flag in this third class. And I add "extend ThirdClass" to other classes' definition, of course.
My problem is when I change the value of first class' flag in the first class' main method, second class is not able to see this change. Namely, it sees the flag with inital value.
I think this is about static variables. But I do not know the solution.
Actually, I have two servers and multi clients. I am trying to simulate differenet situations of these servers for my distributed systems course. Each server has its own data table that is synchronized with other. By simulation, I mean server may be down or up, and when client try to reach down server I need to direct it to other server. So, between clients and servers I need to send information.
How can I share variables between two classes, and easily modify these variables by any class without loss of previous modifications ?
Thank you.
EDIT -- this answer is for a previous version of the question, that does not include anything about clients and multiple servers. This answer is about sharing data between instances of classes.
There are many ways to do something like this. If I understood your approach outlined in the first paragraph, you dont want class1 and class2 to extend class3. You want them to both have a reference to the same instance of class3. If they share a reference to the same object, then changing values on that object will be reflected in both classes. If they extend class3, like you said you tried, then both class1 and class2 will have the properties of class3, but they wont be sharing any data. If class 3 had a property
Object value;
then instances of class1 and class2 would have separate references to separate instances of 'value'.
You need to undertand the relationship between a class, and object instance, and what extending a class means.
Note that this is not really a good way to share information between objects in a real program. You can run into all sorts of concurrency issues. The same is true for a solution that used a global mechanism implemented using static fields.
To do this with static fields do something like:
class SharedData {
public static Object shared1;
}
and then in your class1 and class2 instances you can access
SharedData.shared1
for either set or get.
But I would not do anything like this in any sort of professional context.
You could solve this using statics if it makes sense. When a member is declared static for a class, everyone accessing that member refers to the same instance of that variable, but that doesn't really sound like what you're looking for.
If you want some data to be shared by two classes, you can put the data in a third class and when you create an instance of that third class, be sure the other two classes simply have access to it.
Could you outline what you're trying to accomplish?
Related
I'm working on an existing piece of simulator software, and the structure is basically like this (it has a static member variable containing itself):
public class Simulator {
private Static Simulator instance;
public Simulator(){
instance = this;
//blah
//blah
//other things
}
}
And then a lot of methods access the static instance of the Simulator like this:
for(Foo f : Simulator.instance.getFoo() ){
//blah
}
You get this idea. Basically, the programmers who came before me assumed that there would only ever be one single instance of the Simualtor, so they made it accessible statically.
The problem is that I now want to run multiple instances of it, so this static part is becoming annoying.
Making this work without it being static is probably the best option, I know, but as you can imagine it will take a lot of refactoring and time.
The one thing that does work is to run multiple main methods (so run it several times in my IDE, or run it as a .jar in separate windows). I assume this is because each main method or JVM instance or whatever is acting as a sort of container, so the statics don't interfere?
What I was wondering was, is there a hacky workaround that I can use (at least short-term) to create multiple instances of the simulator, but within some kind of container that makes the static instances not interfere.
I think this is possible using Java class loaders (ClassLoader), but this will lead you into a world of pain. You would have to create sub-applications each using different class loaders. I have never done this, but I believe this is how application servers work.
It will be far easier to refactor your application.
Instead of accessing instance you would have to create multiple instance variables or some dynamic registry like a map where you store the references.
By-the-way, the way that instance is stored in the constructor is very bad practice as it will get overwritten each time new is called and the previous version will be lost. Usually, you would want to just initialise instance with an object.
The quickest and hacky way that I could think of is to override that constructor with a dummy variable
public Simulator(Boolean isDummy){
}
Now you have the option to create a multiple instance of that class without affecting others. Not sure if the parameter overhead is acceptable in your case.
Firstly, I would like to briefly define a state to make sure we're on the same page. (please correct me if I'm wrong, or if you have anything to add)
Mutable variables/objects in the class.
Likely to be used in other classes, therefore creating a reference.
I've heard the main use of static in classes is for utility classes, which basically just provide global access to common methods -- and when states need to be stored, you should use a Singleton. However, I do not understand exactly why states are BAD for static classes? (Please correct me if this ideology is wrong)
I have following scenario, and a confusion to have instance method or static method for dbhelper?
We have a dbhelper class which as name suggest help other classes to work with MySql db.
The db helper class will be used by 2 independent module.
Java Webapp.
Windows based Java app
Currently all the methods in dbhelper class are instance methods
There are 8 methods in dbhelper class among which 3 will be common for webapp and windows app and rest only used by webapp.
Windows app is kind of continuously running 24*7.
Our confusion is such that if we keep methods as instance methods, then we have to crate object of dbhelper class and eventually will be always alive as used by windows app.
What I see advantage of keeping methods as static is no object required.
Note:
I know how static and instance method works.
Google search do not help for this specific example.
The question is too broad for a specific answer. But I can answer with the kinds of things I'd be thinking about, in general.
First of all, if your static methods are going to save state in static class variables, that's not good practice. If there's any state involved, you definitely want to make them instance methods, so that an object of that instance will be holding the state.
You mention that your methods are there to help work with a database. How are they going to access the database? If the database isn't passed as one of the method parameters, then that means the reference to the database has to be stored somewhere, and I think it's best if the dbhelper is an instance that stores a reference to the database (or a reference to some other object that can be used to retrieve the database object) as one of the instance fields.
So I'm going to assume that the methods take a database parameter, or a parameter to some other object that will give you the database object. Given that, there are two things I'd think about when considering whether to make your methods static.
(1) What is the likelihood that the method will change because the requirements change? If it's at all likely, then I'd definitely lean toward making the methods instance methods; in fact, I'd consider making "dbhelper" an abstract class or interface, and having different implementation classes implement the abstract methods in different ways when something changes. That seems to me to be more flexible than just having one static class whose code has to change if the business logic changes. It lets you switch back and forth, or even lets you switch the logic dynamically at run time.
(2) Will you want to mock the method for testing? If your methods access a database, then you will probably want to provide a mock version of the method when unit-testing other classes that call the method, since you want to be able to test them without worrying about setting up the database access and everything. This would also argue for making dbhelper abstract or interface, so that you can provide a mock implementation in addition to your real implementation. (However, some testing platforms like JMockit will let you mock static methods.)
Those are the kinds of things that would lead me toward making the methods instance methods. If you're sure that they don't apply, then it should be OK to make them static methods.
Instead of using static, make use of Singleton design approach for dbHelper class.
something like this,
public class MyDBHelper {
private static MyDBHelper instance;
private MyDBHelper(){}
public static MyDBHelper getInstance(){
if(instance == null){
instance = new MyDBHelper();
}
return instance;
}
public void addRow() {
........
}
}
From other classes, you can access the methods like below
MyDBHelper.getInstance().addRow();
1st : Make all methods of class dbhelpe static and load them when your application gets loaded by any web/application server.This task can be accomplished by static block .
2nd : try to implement Singleton pattern on your dbhelp class ,so that only one object of your class can be shared,this will not leads your application to create object many times,and your application will work faster.
First of all, methods in one class used by multiple callers (web app and Windows app) suggests violation of SRP, so you should be dividing the single DB helper into multiple classes.
Secondly, there are advantages and disadvantages of static and instance methods.
If you practice TDD or DI, it discourages static methods as they are non-mockable (unless you use a framework like Powermock which to me seems a bit hacky.)
If you only do end to end testing, its okay to use static methods.
I am looking at other peoples' code.
I see a class with no non-static fields but in which most of the methods are non-static, requiring you to make an object to access methods that effectively operate statically.
Is there a possible reason for this, that I am just not understanding?
EDIT
Someone asked for examples. Here is some more info.
For instance there is a file manager class. The only fields are static and are Comparators. There are some methods to do things like sort files in a list, count files, copy files, move files to an archive folder, delete files older than a certain time, or create files (basically take a base name as string, and return a File with given base name and date/time tacked on the end.)
9 non-static methods
5 static methods
I don't see a particular rhyme reason for the ones that are static vs non.
One particularly odd thing is that there are two methods for removing files. One that removes a file no matter what, and one that only removes it if it is empty. The former is a static method while the latter is not. They contain the same exact code except the later first checks if the file.length is 0.
Another odd one is a class that does encryption - all fields and methods are static but it has a constructor that does nothing. And an init() method that checks if a static variable contains an object of itself and if not instantiates an object of itself into that field that is then never actually used. (It seems this is done with a lot of classes - init methods that check for an object of itself in a static variable and if not instantiate itself)
private static File keyfile;
private static String KEYFILE = "enc.key";
private static Scrambler sc;
It has methods to encrypt and decrypt and some methods for dealing with key and file.
Does this make sense to anyone? Am I just not understanding the purpose for this stuff? Or does it seem weird?
Objects don't have to have state. It's a legitimate use case to create an instance of a class with only behaviour.
Why bother to create an instance ? So you can create one and pass it around e.g. imagine some form of calculator which adheres to a particular interface but each instance performs a calculation differently. Different implements of the interface would perform calculations differently.
I quite often create classes with non-static methods and no members. It allows me to encapsulate behaviour, and I can often add members later as the implementation may demand in the future (including non-functionality related stuff such as instrumentation) I don't normally make these methods static since that restricts my future flexibility.
You can certainly do it that way. You should look carefully at what the instance methods are doing. It's perfectly okay if they're all operating only on parameters passed in and static final static class constants.
If that's the case, it's possible to make all those methods static. That's just a choice. I don't know how the original developers would justify either one. Maybe you should ask them.
Let me rephrase this question a bit,
Even though methods are non-static why would one declare fields as static?
I have taken below quoting from Java Docs,
Sometimes, you want to have variables that are common to all objects. This is
accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.
For example, suppose you want to create a number of Bicycle objects and assign each a serial number, beginning with 1 for the first object. This ID number is unique to each object and is therefore an instance variable. At the same time, you need a field to keep track of how many Bicycle objects have been created so that you know what ID to assign to the next one. Such a field is not related to any individual object, but to the class as a whole.
For Bicycle example, kindly refer the Java Docs.
Making all methods non-static allows you to override them. This makes it a lot easier to use this class in testing, because instead of the actual implementation you can use a mock that behaves as you want it for the tests. Static methods are, in my book, a code smell and should be avoided unless there's a good reason (e.g. quite trivial utility methods).
Also, at some point in the future you might want to change the behaviour of the methods in some situation, e.g. in the form of a strategy.
In the case of your encryption class, you might want to hand your class an instance of the encryption class to handle encrypting/decrypting, but be able to configure the details in some other place. That would allow you to change the algorithm and much more easily test your own code without also having to test the encryption.
I have a java (android) question.
I have a class (Class A) with its attributes and I have created private classes (Class B and C) inside of class A. Class B and C are AsyncTask.. I don't know if that's important.
I can read the attributes of ClassA from B and C, but, what happen if I modify attribute A from B or C?? I think that these changes are not being permanents,, what it's weird to me because I can access them... So, if I want that the changes are permanents I have to do from ClassB something like,,, classA.atrributeA = atributeA;
I don't know if it's because I'm working with AsyncTask,, or it's the normal behavior. I think that I have some problems with concepts...
Thank you
I think that these changes are not being permanent
That is not correct. Changes made to an A instance's attribute from the nested classes are no different to changes made in other ways.
If they don't appear to be working as you expect, maybe the nested class instances belong to a different instance of A than the one you are looking at. But that is speculation.
Anyway, if you have some concrete "unexpected behaviour" you will need to describe it ... and preferably provide an SSCCE ... if you want us to provide an explanation.
It will work. Here is an example: https://stackoverflow.com/a/5770638/1127492
The real issue is, whether you want to modify these attributes from the inner class as well as the outer class. I recommend to not do that because it will lead to unexpected results if two writers modify the same attribute synchronously. That's why there is a preference option in Eclipse to restrict this access.