I need a class which creates Objects assigning an ID to each Object created. This ID is as usual an int attribute to the class. I want this value (ID) to be increased each time an Object is created and then to be assigned to that Object starting with 1. It strikes me that I need a static int attribute.
How can I initialize this static attribute?
Should I create a separate method to do the increment of the ID (as an ID generator) which is invoked inside the constructor?
What is in general the most effective and well-designed manner to implement that?
You could also try java.util.concurrent.AtomicInteger, which generates IDs in
a atomic way and
sequential
You may use this in a static context like:
private static final AtomicInteger sequence = new AtomicInteger();
private SequenceGenerator() {}
public static int next() {
return sequence.incrementAndGet();
}
Just like you mention use a static int for the id, and increment it when creating new objects.
class MyObject {
private static int counter = 0;
public final int objectId;
MyObject() {
this.objectId = counter++;
}
}
Please note that you need to protect counter++ if MyObject is created by multiple threads (for example using AtomicInteger as the other answers suggest).
I would suggest to use AtomicInteger, which is thread-safe
class MyObject
{
private static AtomicInteger uniqueId=new AtomicInteger();
private int id;
MyObject()
{
id=uniqueId.getAndIncrement();
}
}
Related
I wonder if the following implementation is correct or if there is something simpler to do. My idea is to call the method to initialize the static attribute only once. Since the initialization method needs the id attribute, I guess I have to do it in the constructor.
public class A {
private int id;
private static Point2D[] myArray = new Point2D[10];
public A(int id) {
this.id = id;
if (myArray[0] == null) { // I want the array to be initialized only once.
initArray(id);
}
}
private static void initArray(int id) {
for (int i = 0; i < myArray.length; i++) {
myArray[i] = new Point2D(id, id);
}
}
}
Your code looks good to me. As you have made static members private, so only way it can be set in constructor or in any other method by passing the variable and having a check condition. Static initializer won't work as it runs before constructor, and you won't get ID till then.
The object myArray is actually initialized only once, that is when you call the new operator, and you can't push values in this object because the variable id is not final (and static).
Probably ask to yourself if you really need this class and which are the responsibilities of it.
I am trying to print a final class with static fields on the console, in json format. I am using eclipse.
Stats is a final class that keeps track of object instances that are created or archived. E.g. number of Member instances, number of localities instances etc.
public final class Stats {
public static Integer numMembers = 0;
public static Integer numLocalities = 0;
public static Integer numTowns = 0;
public static void incrementMembers () { numMembers ++; }
public static void incrementLocalities () { numLocalities ++; }
public static void incrementTowns () { numTowns ++; }
}
I ran into problems when I tried to print in json. It does not recognize Stats as an Object instance, which is understandable. Is there a way to print the current state of the Stats class in json?
public static void print () {
System.out.println(GsonBuilder().setPrettyPrinting().create().toJson(Stats));
}
Your current approach will not work with JSON (or any other) serialization, and cannot be made to work the way you want.
A global static object is an anti-pattern as it introduces unwanted coupling into your codebase. There are two approaches to solve this problem, Dependency Injection and Singleton. In both cases, your "statistics" object is a normal object with non-static fields.
public final class Stats {
private int numMembers = 0;
private int numLocalities = 0;
private int numTowns = 0;
public void incrementMembers () { numMembers ++; }
public void incrementLocalities () { numLocalities ++; }
public void incrementTowns () { numTowns ++; }
// Getters...
}
(not sure why you were using Integer, it's not necessary here)
Dependency Injection requires a framework like Spring. If you're not already using Spring then it may be too much change and learning-curve all at one time for you to take on. But it is the best way long-term. An explanation of DI is beyond the scope of an answer here, but the principle is that the framework takes care of instantiating the object and "injecting" it wherever it is needed.
The lighter-weight alternative is the "singleton" pattern (look it up, it is well-documented), where the object contains one static member reference to the single instance that gets created the first time you access it.
public final class Stats {
...
private static Stats instance = null;
public static Stats getInstance()
{
if (instance == null)
instance = new Stats();
return instance;
}
}
(The above is simplistic and ignores threading concerns, study the pattern before using)
Then wherever you need a reference to the (single) Stats instance you do
Stats stats = Stats.getInstance();
In either case you have a real instance that can be serialized.
This question is similar to singleton, but i need to create a class that can allow 'n' number of objects only, Below is my code
public class MSInt {
private static MSInt instance = null;
private static int count = 0;
private MSInt()
{
}
public static MSInt getInstance()
{
if(count < 5){
instance = new MSInt();
count++;
return instance;
}
else
{
return null;
}
}
}
This is working but i am thinking a better solution than this if any.
I think this would be a much cleaner way of doing it. You wouldn't need any counters.
Also it looks nice.
import java.util.ArrayList;
public class MSInt {
private static int MAX_OBJS = 10;
private static ArrayList<MSInt> instances = new ArrayList<MSInt>(MAX_OBJS);
private MSInt() {}
public static MSInt mkInstance() {
if(instances.size() < MAX_OBJS){
MSInt obj = new MSInt();
instances.add(obj);
return obj;
} else {
return null;
}
}
public static ArrayList<MSInt> getInstances() {
return instances;
}
}
Your Code is :
private static MSInt instance = null;
this is overwrite methods;
use like this Array :
private static MSInt[] instance = null;
and use a for loop:
for(int i=0;i<5;i++)
{
instance[i] = new MSInt();
return instance[i];
}
I suggest you to use a decorator pattern
so create a class LimitedList<T> extends AbstractList<T> and override add methods in order to check if size is exceeded
I've put code here (gist)
Few suggestions:
replace public static MSInt getInstance() to public static MSInt getInstance(int number). That way you will be able to specify every time what object you are going to get.
Define difference between instances. What attributes does your instances possess? In your example all objects looks the same - it becomes unclear why do you need more than one of them.
Think about initialization. Do you need lazy initialization, or can you initialize all the instances in class initialization. Then you can declare them public static final and deny defining getInstance()
BTW, enum is class that has exactly n instances (by design). It's very likely that defining MSInt as enum will be the most convenient for you.
Using an array or collection means that garbage collection won't remove any of your instances without your knowledge, and it means you can retrieve instances later if required. Using an an MSInt[] might be most practical because it is already capable of making sure only a certain number of objects exist in it. The getInstance() method then loops through the array and if it finds an empty slot, creates a new instances, puts it in the empty spot and returns the result.
public class MSInt {
private static MSInt[] instances = new MSInt[10];
private MSInt(){ }
public synchronized static MSInt getInstance() /*throws TooManyException*/{
for(int i = 0 ; i<instances.length() ; i++){
if(instances[i]==null){
MSInt ms = new MSInt();
instances[i] = ms;
return ms;
}
}
// throw new TooManyException("There are already 10 instances of MSInt");
return null;
}
}
Some exception handling might also be useful. You could throw a custom exception to show that too many instances already exist. Which would make it much more manageable later because you can then define more robust custom behavior for if the array is already full. By removing the comments in the class above and creating the below class, that should work nicely.
public class TooManyException extends Exception {
public TooManyException(String message){
super(message);
}
}
Hope this helps.
I created SomeConfig to store there static data. However I try to understand witch options is better (or none of both)
Before I had class SomeConfig written like:
public class SomeConfig {
private static int mValue = 8;
private static String mString = "some String";
public static int getValue() {
return mValue;
}
public static void setValue(int value) {
mValue = value;
}
public static String getTheString() {
return mString;
}
public static void setValue(String theString) {
mString = theString;
}
}
Now I changed it to:
public class SomeConfig {
private static SomeConfig mSomeConfig = new SomeConfig();
private int mValue = 8;
private String mString = "some String";
public static int getValue() {
return mSomeConfig.mValue;
}
public static void setValue(int value) {
mSomeConfig.mValue = value;
}
public static String getTheString() {
return mSomeConfig.mString;
}
public static void setValue(String theString) {
mSomeConfig.mString = theString;
}
}
Generally i changed private variables to non-static but API stays the same.
What is a difference between two options I posted?
Thanks,
If you want only one instance of your SomeConfig to exist in your application then you might want to make it a Singleton class. Refer to this link : link
Your second option seems to be the closest to being a Singleton, you just need to make your Default constructor Private to ensure that no other class can create another instance of SomeConfig.
As per my understanding static variables are class variable and those are not require any object for calling or assigning value .The values for those static variables are remains same over the class.Once you assign a value, all object can access that value.
Hope it will help you.
Generally, I think it's a good practice to avoid static variables and methods, unless there is a real need (I guess common use of static is "utility" type method, or constants etc). If you do not want to instantiate the class multiple times or want to ensure single instance of the configuration, I think implementing it as a singleton would be a better way to go here.
I wouldn't recommend using any of the two for configuration purposes.
The difference between these two are just that one uses an instance to hold the values, the other uses static variables.
You might look into having a configuration class that utilises a ResourceBundle to load the values from a .properties file during initialisation.
I would like to create my own class, which had 3 fields. The first field - integer, the second would take objects (Strings, Lists), and the third would take integers. I do not understand two things.
How to organize the storage of variables. I need to write a method in which the Array or List will save these values? How to save in object values?
For second field. If the input is a String or a List so what Type is needed? and if I want to take as primitive types, then what? How to save object?
public class Record {
private int[] number;
private int[] count;
private Object[] code;
public void add(int newNumber, List<String> newCode, int newCount){
return;
};
public void add(List<String> newCode, int newCount,){
return;
};
This doesn't work.
Object nobj = new Object();
nobj = "ss";
Okay. It appears to me that you've misunderstood the purpose of your class. You've written a class to simulate a single Record, but you've written Record to store many values.
Let's re-arrange your class structure a little
public class Record {
private int number;
private int count;
private Object code;
public Record(int number, int count, Object code)
{
this.number = number;
this.count = count;
this.code = code;
}
Then you can create a class, to manage the interface between the Record class, so for example:
public class Storage
{
List<Record> records;
public Storage()
{
this.records = new ArrayList<Record();
}
public void addRecord(int number, int count, Object code)
{
records.add(new Record(number, count, code));
}
}
That way, you're not messing about with lots of different arrays, which are horrible to try to keep track of, Everything is neatly wrapped up inside your objects.
Your issue with the second attribute
Now, it seems you want to store anything in this variable. This is somewhat more complex than your original problem, but I think that Generics will answer your problem for you. I won't write the code for you, but what I can do is give you a demonstration.
public class GenericExample<T>
{
T object;
public GenericExample(T object)
{
this.object = object;
}
}
Okay, so what I've done here is simple. I've created a new class, GenericExample, and I've said that this class has a special type, T. This type is defined at run time, and means you can define plenty of different values. For example.
GenericExample<String> example = new GenericExample<String>("This is a string");
GenericExample<Object> example2 = new GenericExample<Object>(new Object());
See how you can define the type, and pass it in at run time? Now think about applying it to your class structure.
If you really do not need to create your own List, avoid that. Just create your own type of data and use it as a parameter for List:
public class Record {
private int number;
private int count;
private Object code;
// Constructors, setters and getters
};
List<Record> myList = new ArrayList<>();