I'm trying to serialize an ENUM singleton instance (as described by Joshua Bloch in his book Effective Java) to a file. The ENUM instance is a simple JavaBean as this:
public enum ElvisFan implements Serializable{
INSTANCE;
private int totalSongsListened;
private ElvisFan(){
totalSongsListened=0;
}
public void set(int v){
totalSongsListened=v;
}
public int get(){
return totalSongsListened;
}
}
}
I'm successfully using this enum all over my program but when I write this enum to a file using snakeyaml, I just have !!com.chown.ElvisFan 'INSTANCE' in my test.yaml file. This is what I'm doing:
Yaml yaml = new Yaml();
yaml.dump(ElvisFan.INSTANCE, new FileWriter("test.yml");
I also tried this without any luck:
JavaBeanDumper dumper = new JavaBeanDumper();
dumper.dump(ElvisFan.INSTANCE, new FileWriter("test.yml");
Can someone please guide me on this. Thanks!
[Edited]
Code correction.
Singletons don't reakky make any sense. Serialisable singletons make even less sense. There is by definition only one singleton. So when you deserialise a singleton you are not going to get a new object. You will get the same old instance with the same old data.
Enums serialisation is handled specially. They are represented by name and type. No other state is saved, because as previously stated that doesn't make any sense.
I suggest modifying your code to avoid mutable statics.
Enums should not have mutable state. Serialising enums with a single instance can make sense where they implement some other class, such as Comparator, or are use as a key or somesuch.
SnakeYAML treats a List as a sequence not as a mapping even though List has also getters (getFirst()).
Why do you expect enum to be serialized as map ?
You have to provide a custom Representer to dump such an unusual enum as a JavaBean.
Tests contain a lot of examples how to write a custom Representer/Constructor.
Related
I'm developing a library in Java which contains some functionality where some values will have to be run through some function in order to transform or map them in a way. If you want more detail, it's a robotics library where sets of motor output levels will need to be mathematically changed.
Currently, the way I've implemented this is through a Mapper interface with a run method which the map method accepts. Users use it like this:
wheelValues.map(new Mapper() {
#Override
public double run(double input) { ••• }
});
The thing is, I want to include some default implementations of the Mapper interface for user convenience, for example, an absolute value Mapper. I want to make it a property of the Mapper interface some how. What is the best way to approach this, a static inner class or static public fields?
public interface Mapper {
// This?
static final Mapper ABS = new Mapper() {...}
// Or this?
static class Abs implements Mapper {...}
}
Start by using standard library interfaces wherever possible; for example, your Mapper seems like a duplicate of DoubleFunction (or Function<Double, Double>). Absolute value is provided by Math.abs, and you can already refer to it saying Math::abs, no "default implementation" required.
Regarding the question of out-of-the-box implementations, there are two general categories:
Completely pure functions (that have no knobs or settings) are generally implemented as constants somewhere. A good example of this is String.CASE_INSENSITIVE_ORDER, which is a constant of Comparator<String> that does what its name says.
Functions that need a private copy because they have some sort of parameter are implemented as static methods that return an instance of that functional interface. A good example here is Predicate.isEqual(target), which returns a Predicate (object->boolean) instance which returns true if the value examined is equal to the target value (provided when the instance is created): private static final Predicate IS_CORRECT = Predicate.isEqual(correctAnswer).
Make the API as small a reasonably practical. So don't add a extra class where a static method or final field will suffice.
An enum would make a bad choice. As, for example, java.nio.file.StandardCopyOption.
OTOH, you can't allow varying type parameters if you use enum constants or static fields, so a method may be preferable, if only for consistency. As, for example, java.util.Collections.emptySet or java.util.stream.collectors.toSet.
In order not to create too many instances you may want a private static field behind any method.
Avoid the naming classes Default, or other poorly descriptive names. Even if it is the class returned by a default method.
More specifically, in hadoop MapReduce programs if you are using custom classes, the class needs to implement Writable interface. and all its members need to be writable e.g.
class WeatherData implements Writable{
Text stationId;
LongWritable timestamp;
IntWritable temperature;
}
but since Text, LongWritable, IntWritable etc. classes are Writable wrapper classes for primitive data types. You can't do regular manipulations with them like arithmetic operations or string manipulation etc.
having getter setter methods like
public String getStationId(){
return this.stationId.toString();
}
public void setStationId(String stationID){
this.stationId = new Text(stationID);
}
would be beneficial, as the outside world can treat these members as regular java classes but internally they will be stored as objects of writable classes.
My question is whether it is good coding practice or not. what are potential pitfalls with having such getter/setter methods?
It does not seem like a good practice to me. Have a look at the Writable Interface Documentation. All you really need to do is implement the readFields() and write() methods. (Your class members do not need to be writable themselves - See the example in the documentation.)
When the Gang of four introduced the singleton pattern, they also had to explain, why not to use static class fields and method instead. The reason was: the possibility to inherit. For Java it had sense - we cannot normally inherit the class fields and methods.
Later the "Effective Java" book appeared. And we know now that the existence of reflection destroys the singularity of the singleton class with private constructor. And the only way to make a real SINGLEton is to make it as a single item of an enumeration. Nice. I had done some myself this way.
But a question remains: While we cannot inherit from enumeration, what is the use of this singleton? Why we don't use these old good static/class fields and methods?
Edit. Thanks to the #bayou.io I see that in https://softwareengineering.stackexchange.com/a/204181/44104 there is a code that can trick the enum, too, and create again two exemplars of the enum singleton. The other problems are mentioned there, too. So, there is no need to use enum instead of the usual singleton class pattern, too? BTW, all enum pluses that are mentioned here till now, work for singleton classes, too.
what is the use of this singleton? Why we don't use these old good static/class fields and methods?
Because enum is an object so it can not only be passed around but also implement interfaces.
Also since we are making a class, we can use the different public/private options available to all kinds of classes.
So in practice, we can make a singleton that implements an interface and then pass it around in our code and the calling code is non the wiser. We can also make the enum class package private but still pass it around to other classes in other packages that expect the interface.
If we used the static methods version, then the calling class would have to know that this object is a singleton, and our singleton class would have to be public so the other classes can see it and use it's methods.
There's nothing particularly wrong with the "good old fashioned singleton", enum "singletons" are just convenient - it saves you the need to muck around with boiler-plated code that looks the same in every singelton.
To me, a singleton makes sense wherever you want to represent something which is unique in its kind.
As an example, if we wanted to model the Sun, it could not be a normal class, because there is only one Sun. However it makes sense to make it inherit from a Star class. In this case I would opt for a static instance, with a static getter.
To clarify, here is what I'm talking about :
public class Star {
private final String name;
private final double density, massInKg;
public Star(String name, double density, double massInKg) {
// ...
}
public void explode() {
// ...
}
}
public final class Sun extends Star {
public static final Sun INSTANCE = new Sun();
private Sun() { super("The shiniest of all", /**...**/, /**...**/); }
}
Sun can use all the methods of Star and define new ones. This would not be possible with an enum (extending a class, I mean).
If there is no need to model this kind of inheritance relationships, as you said, the enum becomes better suited, or at least easier and clearer. For example, if an application has a single ApplicationContext per JVM, it makes sense to have it as a singleton and it usually doesn't require to inherit from anything or to be extendable. I would then use an enum.
Note that in some languages such as Scala, there is a special keyword for singletons (object) which not only enables to easily define singletons but also completely replaces the notion of static method or field.
ENUM singletons are easy to write. It will occupy very less code, which is clean & elegant if you compare with implementation of lazy singleton with double synchronized blocks
public enum EasySingleton{
INSTANCE;
}
Creation of ENUM instance is thread safe.
ENUM singletons handled serialization by themselves.
conventional Singletons implementing Serializable interface are no longer remain Singleton because readObject() method always return a new instance just like constructor in Java. you can avoid that by using readResolve() method and discarding newly created instance by replacing with Singeton
private Object readResolve(){
return INSTANCE;
}
Have a look at this article on singleton
I am making a text adventure engine in Java, and in order to save memory, I have a database object that holds all the currently scraped items from an XML document. I want to use it from several different classes. How can I make it available to my classes? Currently I'm using a null static field with an appropriate mutator method.
It might be useful to use a Singleton for this.
You can use a enum type. Joshua Bloch says in his book Efective Java: a single-element enum type is the best way to implement a singleton.
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
Lets say you have a class SomeClass which has its own implementation of toString(), and also has the ability to parse a new instance of itself by reading that same string.
Which of these methods do you prefer, or find better to use?
You can either define it as another constructor:
public SomeClass(String serializedString);
or you can define it as a static method, which in turn creates a new instance (by one of the other constructors, does some with it, and returns the new instance:
public static SomeClass toObject(String serializedString);
Does it even matter? (my hunch is there is no case this matters, but I am trying to make sure)
My own preference is to keep the parsing logic out of the constructor. That way it can call the appropriate constructors (possibly private) as necessary. It doesn't have to depend on default object construction and so on. So I would go with the toSomeClass() method.
Also, it is not immediately clear that SomeClass(String) will parse an object based on the serialization string. There may be many other meanings to a constructor which takes a String. The toSomeClass() static method makes this clear.
I agree with Avi's recommendation. I'd like to add two more advantages:
A static factory method allows you to return null, which a constructor can't.
A static factory method allows you to return a subclass of its defined return type, which can help provide forward compatibility.
One exception: if you're writing a simple value type and using the immutable pattern, I see no reason to use a static factory method.
The static method has the advantage that you can then use the string-reading constructor for something else. Also in general it's better to use static factories than constructors in any nontrivial classes. It gives you more flexibility.
A Java convention for such static methods is:
public class Foo {
// ...
public Foo parseFoo (String s) {...}
// ...
}
as in the standard parseInt(...), parseLong(...), parseDouble(...), etc. Unfortunately, Sun also gave us a different convention with the wrapper classes, as in Boolean.valueOf(...). However, I'd pick one of those conventions and follow it consistently.
To keep some specific logic (like parsing from string) out of constructor is good design policy.
Constructor job is mainly object creation. Initialization and creation of it's fields.
Serialization logic need to be separated from creation. Firstly you may wan't to create separate static method, secondly in evolution of your class you may want to implement some kind of Serializable interface and delegate reading/writing job to another class.
Another advantage to a static constructor is that you can give it a meaningful name. In this case, I would suggest parse:
SomeClass inst = SomeClass.parse("wibble");