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.
Related
For example:
In Class One
int killcount = 0;
In Class Two
killcount = 5;
All I want to do I get the variable from one class to another class. How would I do that?
Before trying to work with Bukkit I'd recommend you to get some Java experience first. That's not meant as an insult, but it can get quite confusing if you do it the other way round. Anyways, if you still want to know the answer to your question:
You'll have to create a getter & setter for your "killcount" variable.
class Xyz {
private int killcount;
public void setKillcount(int killcount) {
this.killcount = killcount;
}
public int getKillcount() {
return this.killcount;
}
}
Of course this is a simplified version without checks, but if you want to access the variable from a different class you can create an instance and use the methods to modify it.
public void someMethod() {
Xyz instance = new Xyz();
instance.setKillcount(instance.getKillcount() + 1);
//this would increase the current killcount by one.
}
Keep in mind that you'll have to use the same instance of the class if you want to keep your values, as creating a new one will reset them to default. Therefore, you might want to define it as a private variable too.
Consider the examples
public class Test {
public int x = 0;
}
This variable x can be accessed in another class like
public class Test2 {
public void method() {
int y = new Test().x;
// Test.x (if the variable is declared static)
}
}
Ideally, the instance variables are made private and getter methods are exposed to access them
public class Test {
private int x = "test";
public int getX() {
return x;
}
public void setX(int y) {
x = y;
}
}
I came across this kind of example and had difficulty to understand it's actuall purpose:
class YieldDemo extends Thread
{
static boolean finished = false;
static int sum = 0;
public static void main (String [] args)
{
new YieldDemo ().start ();
for (int i = 1; i <= 50000; i++)
{
sum++;
if (args.length == 0)
Thread.yield ();
}
finished = true;
}
public void run ()
{
while (!finished)
System.out.println ("sum = " + sum);
}
}
I've never seen this kind of implementation - why initiating a the new class inside the same class object and not outside the class? is there any particular reason?
In fact you are outside of the class object itself. The main method is a static method, thus it has no dependency on any object instance.
You could also move the main method to any other java file. In general it will also work. However, you need to put static methods in some file. As every java file needs to be a class, you may put the method in the class it works for. For example, the class Math in java is a pure utility class, it has no non-static method.
However, if you create something like this:
public final class Value {
private final int mValue;
public Value(int value) {
mValue = value;
}
public int getValue() {
return mValue;
}
public Value increase() {
return new Value(mValue + 1);
}
}
It can actually make sense if you want Value to be immutable (not change its internal value). So, calling increase() does not increase the value itself but creates a new instance of this object, with an increased value.
I'm studying basic software design pattern.
The basic implementation of singleton classes are written like this:
public class MyObject{
private volatile static MyObject obj;
private MyObject(){/*Do some heavy stuff here*/}
public static synchronized MyObject getInstance(){
if(obj==null)
obj=new MyObject();
return obj;
}
}
But as I have undestood calling synchronized methods can be heavy.
I while back I red a book the introduced this kind of implementation of Singleton class:
public class MyObjectHolder {
private volatile static Supplier<MyObject> myObjectSupplier = () -> createMyObj();
//myObjectSupplier is changed on the first 'get()' call
public static MyObject getMyObject(){
return myObjectSupplier.get();
}
private static synchronized MyObject createMyObj(){
class MyObjectFactory implements Supplier<MyObject> {
private final MyObject clockTimer = new MyObject();
public MyObject get() { return clockTimer; }
}
if(!MyObjectFactory.class.isInstance(myObjectSupplier)) {
myObjectSupplier = new MyObjectFactory();
}
return myObjectSupplier.get();
}
public static class MyObject{
private MyObject(){
/*Do some heavy stuff here*/
}
public void someMethod(){
/* ... */
}
}
}
...
{
/*In main MyObject instantiation*/
MyObjectHolder.MyObject obj = MyObjectHolder.getMyObject();
}
Now after the first call for 'createMyObj()' has been has been finished, there is no heavy burden of synchronized method calling and the is no if check neither.
Do you think there is something wrong with this kind of implementation?
ps. MyObject does not have to be an inner class of MyObjectHold but I thought it looked nice.
[UPDATED] Another solution that is called Initialization on Demand Holder idiom :
public class SingletonObject {
private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger();
private static final AtomicInteger INVOKE_COUNT = new AtomicInteger();
private static final class LazyHolder {
private static final SingletonObject INSTANCE = new SingletonObject();
}
private SingletonObject() {
System.out.println("new SingletonObject");
INSTANCE_COUNT.getAndIncrement();
}
public static SingletonObject getInstance() {
INVOKE_COUNT.getAndIncrement();
return LazyHolder.INSTANCE;
}
public static int getInstanceCount() {
return INSTANCE_COUNT.get();
}
public static int getInvokeCount() {
return INVOKE_COUNT.get();
}
}
to prove that it's thread-safe :
public static void main(String[] args) throws Exception {
int n = 1000;
List<Callable<SingletonObject>> invokers = new ArrayList<>();
for (int i = 0; i < n; i++) {
invokers.add(SingletonObject::getInstance);
}
ExecutorService es = Executors.newFixedThreadPool(n);
es.invokeAll(invokers);
es.shutdown();
System.out.println("Number of Instances = " + SingletonObject.getInstanceCount());
System.out.println("Number of Invokes = " + SingletonObject.getInvokeCount());
}
Output :
new SingletonObject
Number of Instances = 1
Number of Invokes = 1000
EDIT (after #Holger's comment) :
the use of the Nested Holder Class is somewhat necessary to Lazily Initialize the SingletonObject.
public class SingletonObject {
private static final SingletonObject INSTANCE = new SingletonObject();
private SingletonObject() {
System.out.println("new SingletonObject");
}
public static SingletonObject getInstance() {
return INSTANCE;
}
public static void anotherStaticMethod() {
System.out.println("I don't need the SingletonObject Instance...");
}
}
So what happens if someone invokes the anotherStaticMethod()?
new SingletonObject
I don't need the SingletonObject Instance...
UPDATE :
The page at WIKIPEDIA says :
The implementation of the idiom relies on the initialization phase of execution within the Java Virtual Machine (JVM) as specified by the Java Language Specification (JLS). When the class SingletonObject is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition LazyHolder within it is not initialized until the JVM determines that LazyHolder must be executed. The static class LazyHolder is only executed when the static method getInstance is invoked on the class SingletonObject, and the first time this happens the JVM will load and initialize the LazyHolder class. The initialization of the LazyHolder class results in static variable INSTANCE being initialized by executing the (private) constructor for the outer class SingletonObject. Since the class initialization phase is guaranteed by the JLS to be serial, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization. And since the initialization phase writes the static variable INSTANCE in a serial operation, all subsequent concurrent invocations of the getInstance will return the same correctly initialized INSTANCE without incurring any additional synchronization overhead.
This gives a highly efficient thread-safe "singleton" cache, without synchronization overhead; benchmarking indicates it to be far faster than even uncontended synchronization. However, the idiom is singleton-specific and not extensible to pluralities of objects (e.g. a map-based cache).
Also keep an eye on this.
The easiest way to implement the Singleton pattern in java is to simply make the class an enum instead:
public enum MyObject{
Obj;
MyObject(){/*Do some heavy stuff here*/}
}
Obj is guaranteed by the specification to only be created once on the first use of it.
Singleton pattern breaks Single Responsibility Principle (SRP) - because the class has to do two things:
It's primary task
Enforcing singleton-ness.
Your second approach is trying to delegate this 'Enforcing singleton-ness' to a separate class - following SRP. If you are using a dependency injection framework like spring, you can achieve the same effect by only defining MyObject class and declaring this class with a 'singleton' scope in the spring context.
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 am trying to implement an interface in Java to use different types of databases for one application.
My though was to create an abstract class with the common interface and two static variables which are then overwritten by the subclasses. I then wanted to add a Class[] List with the classes of all available subclasses to the abstract class as well as a couple of functions that allow the determination of the correct class to be used.
The goal is to first get a list of all available database types and let the user choose one. Afterwards another function should translate the name (which could be localized) to the IDENTIFIER which is specified in the subclass. Finally a third function allows the instantiation of an object by giving such an IDENTIFIER.
My abstract class would look something like this:
public abstract class DataBase {
public static final IDENTIFIER = "";
public static final NAME = "";
private static final Class[] dbTypes = new Class[]{PostgreSQL.class, MySQL.class};
public static String[] getNameList() {
String[] names = new String[dbTypes.length];
for(int i = 0; i < dbTypes.length; i++){
names[i] = dbTypes[i].NAME; //Cannot access the static variable this way.
}
return names;
}
public static String getIdentifierForName(String name) {
for(int i = 0; i < dbTypes.length; i++){
if(name.equals(dbTypes[i].NAME){
return dbTypes[i].IDENTIFIER;
}
}
return "";
}
public static DataBase getInstanceOf(String identifier) {
for(int i = 0; i < dbTypes.length; i++){
if(identifier.equals(dbTypes[i].IDENTIFIER) {
return dbTypes[i].newInstance();
}
}
return null;
}
}
The Child classes would look something like this:
public class MySQL extends DataBase {
public static final IDENTIFIER = "ab.cde.MySQL";
public static final NAME = "MySQL";
...
}
public class PostgreSQL extends DataBase{
public static final IDENTIFIER = "ab.cde.PostgreSQL";
public static final NAME = "PostgreSQL";
...
}
My problem now is, that I cannot access the static variables from the Class object. Obviously the dbTypes list does not contain any typed classes. I tried changing the type of the Array to Class<? extends DataBase>, but I get an error Cannot create a generic array of Class<? extends DataBase> I also tried checking the classes with isAssignableFrom() and then casting the class, but I was still not able to access the static variables.
For now I have two solutions which are working:
Hardcode all existing subclasses into each function if(PostgreSQL.NAME.equals(name)){...}etc.
However, if I add new subclasses, I only want to have to add them at one point in my implementation.
Instead of using a Class[] array, I can use an array of DataBase[] with instances of each class. However, I would think this is bad practice to instantiate each available DataBase subclass, even though I only need one in the end.
Since I have never done such a thing before I might also be approaching the problem completely wrong. Maybe I am missing the correct way in which something like this is usually done?
Thank you for your help.
There are no "abstract properties" in Java. You have to create two astract methods in the DataBase class, like this:
public abstract class DataBase {
// No "abstract propeties"
public abstract String getDBName();
public abstract String getDBIdentifier();
// etc etc...
}
and then, in each subclass:
public class MySQL extends DataBase {
public static final IDENTIFIER = "ab.cde.MySQL";
public static final NAME = "MySQL";
#Override
public String getDBName() {
return NAME;
}
#Override
public String getDBIdentifier() {
return IDENTIFIER;
}
// etc etc...
}
When using the classes, you can just cast to DataBase (not MySQL or PostgreSQL) and call the two abstract methods.
Therefore, in order to solve your "pick a database class" problem, I would create a configuration file that contains the names of the databases and the corresponding class, and instantiate it with reflection (newInstance()) as needed.
As an alternative, you can use reflection to access the static variables like Nikita's answers suggested, or you can just use the name of the class as the identifier of the database it supports, like this (not tested):
public abstract class DataBase {
private static final Class[] dbTypes = new Class[]{PostgreSQL.class, MySQL.class};
public static Class getDBClass(String type) {
for (Class c : dbTypes) {
if (c.getSimpleName().toLowerCase().equals(type.toLowerCase())) {
return c;
}
}
return null;
}
public static Set<String> getSupportedDB() { // <-- you populate a dropdown menu with this
Set<String> supported = new HashSet<String>();
for (Class c : dbTypes) {
supported.add(c.getSimpleName());
}
return supported;
}
// etc etc...
}
However, I don't like this solution and I would not use it.
You can use reflection to get values for each class:
public static String[] getNameList(){
String[] names = new String[dbTypes.length];
for(int i=0; i<dbTypes.length; i++){
Field f = dbTypes[i].getField("NAME");
names[i] = f.get(null);
}
return names;
}
But it might be slow.
Also I'd suggest to create separate enum DBRegistry that will contain names, identifiers and classes:
public enum DBRegistry {
MYSQL("ab.cde.MySQL", "MySQL", MySQL.class),
POSTGRESQL("ab.cde.PostgreSQL", "PostgreSQL", PostgreSQL.class);
private String name;
private String identifier;
private Class<?> dbClass;
private DBRegistry(String identifier, String name, Class<?> dbClass) {
this.identifier = identifier;
this.name = name;
this.dbClass = dbClass;
}
// Getters...
}
You can iterate on all items in registry using DBRegistry.values
Not tested, but I would suggest something like this. You could register databases by calling DataBase.registerDataBase(new DataBase(...))); which may be invoked from the main file.
public class DataBase {
private final static List<DataBase> INSTANCES = new ArrayList<DataBase>();
private final String identifier;
private final String name;
private final Class<?> dbType;
public DataBase(String identifier, String name, Class<?> dbType) {
this.identifier=identifier.toString();
this.name=name.toString();
this.dbType=dbType;
}
String getIdentifier() {return identifier;}
String getName() {return identifier;}
Class<?> getDbType() {return dbtype;}
public synchronized static void registerDatabase(DataBase database) {
database.getClass();
INSTANCES.add(database);
//may check if already registered and either fail or replace it
}
public synchronized static List<DataBase> getNameList() {
return new ArrayList<DataBase>(INSTANCES);
}
public synchronized static List<String> getNameList() {
List<String> names = new ArrayList<String>(INSTANCES.size());
for (Database db:INSTANCES) names.add(db.getName());
return names;
}
public synchronized static String getIdentifierForName(String name) {
for(DataBase db:INSTANCES){
if(name.equals(db.getName())) return db;
}
return null;
}
public synchronized static DataBase getInstanceOf(String identifier) {
for(DataBase db:INSTANCES){
if(identifier.equals(db.getIdentifier())) return db;
}
return null;
}
}
}
I would advise to keep it simple, never more than necessary to utilize in the actual application. It is easier to extend things than to re-factor code to accomodate for additional complexity. Most of the stuff you mention are merely artefacts of your problem solving, not the actual requirements of your application per se. And it so happens, that a modern object-oriented language has everything you need, and you can implement a good design without reflection and without resorting to static properties and string identifiers.
Remember to rely on the compiler rather than runtime for whatever you know in advance - anything that is known not to change from one application run to another, does not need reflection, because it does not involve runtime variables! I would go for interfaces, classes implementing them, and more importantly the Factory pattern to abstract using these classes:
interface Database
{
void query(String sqlString);
}
class MySQLDatabase implements Database
{
public void query(String sqlString)
{
}
}
class PostgreSQLDatabase implements Database
{
public void query(String sqlString)
{
}
}
class DatabaseFactory
{
Database connectDatabase()
{
/// F.e. return new MySQLDatabase();
}
}
The whole "database abstraction layer" has been done to death already anyway, giving birth to DBA, ODBC and other software stacks that solve your problem. You should let yourself be inspired by these, unless you are sure your particular way of solving this yields advantages that can be proven. If you want to go about this in a professional way, of course. If you want to educate yourself, by all means, use reflection, strings in place of more specific objects, and tight-coupling instead of aggressive modularity.