I am having quite a bit of problems naming variable automatically in java.
The problem in question :
I am making a class Point (different from java.awt.Point
). It has an attribute this.name
. From a testPoint.java
I just create a Point
and print its name.
To create a Point I have two linked constructor :
public Point() {
this("AutoName");
}
public Point(String name) {
this.name = name;
}
If a name is given in the testPoint.java
, the point will be named according to that name. If no name is given the Point will be named AutoName
.
What i want is that if no name is given the first no named Point gets AutoName1
as a name, the second AutoName2
etc.
Is there a way to do that without introducing new classes ? It would be easy if I can create a global variable in java like in C and Python but I think that does not respect the encapsulation principle...
CodePudding user response:
Use a static int
in the class to hold the number of instanciation
class Point {
static int creationCount = 1;
String name;
public Point() {
this("AutoName" (creationCount ));
}
public Point(String name) {
this.name = name;
}
@Override
public String toString() {
return "Point{name='" name "'}";
}
}
System.out.println(new Point()); // Point{name='AutoName1'}
System.out.println(new Point("abc")); // Point{name='abc'}
System.out.println(new Point()); // Point{name='AutoName2'}
System.out.println(new Point("bcd")); // Point{name='bcd'}
CodePudding user response:
The accepted solution is fine for a single-thread application, e.g. when there is a single loop creating the points.
However, in case there are several threads creating the instances of Point
class, the values of creationCount
may repeat for different points, and defining the counter variable as static volatile
does not guarantee the uniqieness of its values because pre- and post-increments are not atomic operations.
So, in general case it may be better to use more thread-safe AtomicInteger
for the mentioned purpose:
import java.util.concurrent.atomic.AtomicInteger;
class Point {
static AtomicInteger creationCount = new AtomicInteger(1);
String name;
public Point() {
this("AutoName" creationCount.getAndIncrement());
}
public Point(String name) {
this.name = name;
}
@Override
public String toString() {
return "Point{name='" name "'}";
}
}
CodePudding user response:
You can use a static variable to do that:
class Point {
static int counter = 1;
String name;
public Point() {
this("AutoName" counter);
counter ;
}
public Point(String name) {
this.name = name
}
}