How to add null values to ConcurrentHashMap - java

I have a ConcurrentHashMap which is called from different threads to put values in it. I have to insert null values, but ConcurrentHashMap doesn't allow null values. Is there a way to do that or an alternate option to do this in Java?

Rather than using null, which has no semantic meaning and is generally considered an antipattern, represent this "absent" notion as a concrete type that reflects your intent and forces callers to account for it properly.
A common solution is to use Optional (for pre-Java 8, use Guava's Optional) to represent the absence of a value.
So your map would have a type ConcurrentHashMap<Key, Optional<Value>>.
Another option is to represent whatever you intend to mean by null more directly in the type you're storing in the map, e.g. if null is supposed to mean "this used to exist, but no longer" you might create a class structure like so:
public abstract class Resource {
public abstract void doSomething();
public abstract ClosedResource close();
}
public class ActiveResource extends Resource {
public void doSomething() { ... }
public ClosedResource close() { ... }
}
public class ClosedResource extends Resource {
public void doSomething() { /* nothing to do */ }
public ClosedResource close() { return this; }
}
And then simply have a ConcurrentHashMap<Key, Resource>. There are pros and cons to both approaches depending on your exact needs, but both are objectively better than putting null values in your map.
You might also simply be able to avoid adding nulls at all - if you can't create a clear semantic meaning for null that's different from simply being absent (as suggested above), just use absence in the map to convey what you care about, rather than distinguishing between the absent and present-but-null cases.

One simple answer is "If the value is null, don't try to add it".
Another answer is to take a page from .NET and introduce a Nullable. Your values would be an instance of Nullable.
public class Nullable<T> {
private final T obj;
public Nullable(T t) {
obj = t;
}
public T get() {
return obj
}
}
You can successfully make instances of Nullable with a null value. You can get the value out with get().
--- This is the old version of the answer ---
First, why would you need to put a null key? That would seem like an issue in your design.
That being said, you could use a stand-in object for null. Say your key is KeyLikeThing. Normally a KeyLikeThing has attributes which affect its hash and equals properties. You can have an instance of KeyLikeThing is null in your world. When ever your client wants to put a null, it uses the instance of KeyLikeThing.
public class KeyLikeThing {
public static final KeyLikeThing NULL = new KeyLikeThing();
// Other KeyLikeThing related stuff.
}
public class Storage<T> {
private ConcurrentHashMap m = new ConcurrentHashMap();
public T put(KeyLikeThing k, T val) {
KeyLikeThing kl = k == null ? KeyLikeThing.NULL : k;
return m.put(kl, val);
}
}

Related

Why java.util.Optional is not Serializable, how to serialize the object with such fields

The Enum class is Serializable so there is no problem to serialize object with enums. The other case is where class has fields of java.util.Optional class. In this case the following exception is thrown: java.io.NotSerializableException: java.util.Optional
How to deal with such classes, how to serialize them? Is it possible to send such objects to Remote EJB or through RMI?
This is the example:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Optional;
import org.junit.Test;
public class SerializationTest {
static class My implements Serializable {
private static final long serialVersionUID = 1L;
Optional<Integer> value = Optional.empty();
public void setValue(Integer i) {
this.i = Optional.of(i);
}
public Optional<Integer> getValue() {
return value;
}
}
//java.io.NotSerializableException is thrown
#Test
public void serialize() {
My my = new My();
byte[] bytes = toBytes(my);
}
public static <T extends Serializable> byte[] toBytes(T reportInfo) {
try (ByteArrayOutputStream bstream = new ByteArrayOutputStream()) {
try (ObjectOutputStream ostream = new ObjectOutputStream(bstream)) {
ostream.writeObject(reportInfo);
}
return bstream.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
This answer is in response to the question in the title, "Shouldn't Optional be Serializable?" The short answer is that the Java Lambda (JSR-335) expert group considered and rejected it. That note, and this one and this one indicate that the primary design goal for Optional is to be used as the return value of functions when a return value might be absent. The intent is that the caller immediately check the Optional and extract the actual value if it's present. If the value is absent, the caller can substitute a default value, throw an exception, or apply some other policy. This is typically done by chaining fluent method calls off the end of a stream pipeline (or other methods) that return Optional values.
It was never intended for Optional to be used other ways, such as for optional method arguments or to be stored as a field in an object. And by extension, making Optional serializable would enable it to be stored persistently or transmitted across a network, both of which encourage uses far beyond its original design goal.
Usually there are better ways to organize the data than to store an Optional in a field. If a getter (such as the getValue method in the question) returns the actual Optional from the field, it forces every caller to implement some policy for dealing with an empty value. This will likely lead to inconsisent behavior across callers. It's often better to have whatever code sets that field apply some policy at the time it's set.
Sometimes people want to put Optional into collections, like List<Optional<X>> or Map<Key,Optional<Value>>. This too is usually a bad idea. It's often better to replace these usages of Optional with Null-Object values (not actual null references), or simply to omit these entries from the collection entirely.
A lot of Serialization related problems can be solved by decoupling the persistent serialized form from the actual runtime implementation you operate on.
/** The class you work with in your runtime */
public class My implements Serializable {
private static final long serialVersionUID = 1L;
Optional<Integer> value = Optional.empty();
public void setValue(Integer i) {
this.value = Optional.ofNullable(i);
}
public Optional<Integer> getValue() {
return value;
}
private Object writeReplace() throws ObjectStreamException
{
return new MySerialized(this);
}
}
/** The persistent representation which exists in bytestreams only */
final class MySerialized implements Serializable {
private final Integer value;
MySerialized(My my) {
value=my.getValue().orElse(null);
}
private Object readResolve() throws ObjectStreamException {
My my=new My();
my.setValue(value);
return my;
}
}
The class Optional implements behavior which allows to write good code when dealing with possibly absent values (compared to the use of null). But it does not add any benefit to a persistent representation of your data. It would just make your serialized data bigger…
The sketch above might look complicated but that’s because it demonstrates the pattern with one property only. The more properties your class has the more its simplicity should be revealed.
And not to forget, the possibility to change the implementation of My completely without any need to adapt the persistent form…
If you would like a serializable optional, consider instead using guava's optional which is serializable.
The Vavr.io library (former Javaslang) also have the Option class which is serializable:
public interface Option<T> extends Value<T>, Serializable { ... }
It's a curious omission.
You would have to mark the field as transient and provide your own custom writeObject() method that wrote the get() result itself, and a readObject() method that restored the Optional by reading that result from the stream. Not forgetting to call defaultWriteObject() and defaultReadObject() respectively.
If you want to maintain a more consistent type list and avoid using null there's one kooky alternative.
You can store the value using an intersection of types. Coupled with a lambda, this allows something like:
private final Supplier<Optional<Integer>> suppValue;
....
List<Integer> temp = value
.map(v -> v.map(Arrays::asList).orElseGet(ArrayList::new))
.orElse(null);
this.suppValue = (Supplier<Optional<Integer>> & Serializable)() -> temp==null ? Optional.empty() : temp.stream().findFirst();
Having the temp variable separate avoids closing over the owner of the value member and thus serialising too much.
Just copy Optional class to your project and create your own custom Optional that implements Serializable. I am doing it because I just realized this sh*t too late.
the problem is you have used variables with optional. the basic solution to avoid this, provide the variable without optional and get them as optional when you call the getter like below. Optional<Integer> value = Optional.empty(); to Integer value = null;
public class My implements Serializable {
private static final long serialVersionUID = 1L;
//Optional<Integer> value = Optional.empty(); //old code
Integer value = null; //solution code without optional.
public void setValue(Integer value ) {
//this.value = Optional.of(value); //old code with Optional
this.value = value ; //solution code without optional.
}
public Optional<Integer> getValue() {
//solution code - return the value by using Optional.
return Optional.ofNullable(value);
}
}

java #Nonnull annotation in a method that returns null

I have a method that gets something from a hashmap, a simplified example (that doesn't make much sense but is good enough for now) is:
private Map<String,String> map = new HashMap<String,String>();
public String get(String key) {
return map.get(key);
}
This method can return a null when an entry doesn't exist for a given key obviously. The thing is, I want to annotate this method with #NonNull (because it is used in a gazillion places and I don't like Intellij spamming me with inspection warnings about producing a NPE and I don't want to turn off that inspection, and I also don't want to check whether the value returned is different than null everywhere I call this method. This is because I always use this method with a bunch of keys that are ALWAYS in the map. So due to the program logic this method is bound to return a #NonNull value.
I am tempted to just annotate it with a #NonNull, but who knows someone may call it with something other than the defined keys somewhere and actually cause a NullPointerException.
What would you do? An assertion sounds tempting to me.. Or would you just change the method to throw a RuntimException ? Or an AssertionError?
Thanks.
Edit:
here's the actual implementation:
/**
* Typesafe heterogeneous container pattern - implementation
*/
public class HandlersMap {
private final Map<Class<? extends TableHandler>, TableHandler> handlers;
public HandlersMap() {
handlers = new HashMap<Class<? extends TableHandler>, TableHandler>();
putHandler(RolesTableHandler.class, new RolesTableHandler());
putHandler(UsersTableHandler.class, new UsersTableHandler());
putHandler(DevicesTableHandler.class, new DevicesTableHandler());
}
private <T extends TableHandler> void putHandler(#NonNull final Class<T> type, #NonNull final T instance) {
handlers.put(type, type.cast(instance));
}
#NonNull
public <T extends TableHandler> T getHandler(#NonNull final Class<T> type) {
assert handlers.get(type) != null;
return type.cast(handlers.get(type));
}
public Collection<TableHandler> values() {
return handlers.values();
}
public int size() {
return handlers.size();
}
public Map<Class<? extends TableHandler>, TableHandler> getMap() {
return this.handlers;
}
}
Annotating with #Nonnull without verifying if the given key exists is definitely the wrong thing to do.
Since you seem to indicate that the given key is expected to exist, this means a missing key is an invalid argument, so checking for this case and throwing an IllegalArgumentException for missing elements would be the proper thing to do.
Alternatively, depending on how your map is initialized, you might want to consider creating an enum for your key values, use an EnumMap instead of a HashMap, and have your get() method take this enum rather than a free-form String. That way, you would have some compile-time checking to ensure proper values are used as well.
Even in that case though, you'd still need to check for existence, just in case the requested enum value is not yet added to the map.

Best design pattern for a scenario

We have a class called Variable which represents a singlevalue or compound value. For example, it can hold an integer,or a boolean,or a String etc... (single valued) or some compound value which can be list of Strings, integers or other Variables.
We serialize these objects and in the stream all these values are represented as strings. Whenever we serialize or deserialize there is a type conversion happening.
There are also some optional features or ways you can fill values in these variables. For example you can define a Variable to be populated from a webpage - For a given Variable we query a cache to understand if it should be populated from a webpage. Whenever someone does getValue() on the Variable we populate the value.
We also want to track changes of some variables. For example, I can choose to record or do some action whenever the value of a variable is read or changed.
As you can see that this is a hierarchical structure because variable can contain other variables. We wanted to find the best way to solve this.
Currently we have only one class called Variable which has so many if/else conditions and the code is very complex.
For example, getValue() code does the following:
if(query the cache to see if it needs population from webpage)
do something
else(---)
do something
else(if read should be recorded-find from cache)
do something etc...
Is there any pattern to design my classes in such a way that all my population from webpage logic can go in to one class, tracking logic in some other class, type conversion logic in some other class etc... to make it more readable.
Chain of Responsibility Each chained element in the Composite gets to do it's bit, but you have to spend some time configuring the runtime structure just so.
Possibly just a Composite or Observer for the getValue() scenario (but sounds more like Composite to me).
EDIT:
One could argue that the implementation below is in fact a case of "Chain of Responsibility", as a composite variable will delegate the responsibility of setting values to its children.
END EDIT
Here's a simple example using Observer and Composite. NOT TESTED just to give you the general feel for the solution...
I have not implemented stuff like serializing/deserializing.
In this solution you have compound values and atomic values, and you can add some observer to be executed before value is set.
package dk.asj.variables;
public abstract class VariableBase {
public interface Observer {
void onSet(final Value val, final VariableBase var);
}
private Observer obs = null;
public void setObserver(final Observer obs) {
this.obs = obs;
}
public void setValue(final Value val) {
if (obs != null) {
obs.onSet(val, this);
}
internalSetValue(val);
}
protected abstract void internalSetValue(final Value val);
public abstract Value getValue();
}
package dk.asj.variables;
import java.util.List;
public interface Value {
int getIntValue();
String getStringValue();
List<Value> getCompositeValue();
}
package dk.asj.variables;
public class SimpleVariable extends VariableBase {
private Value val = null;
#Override
protected void internalSetValue(final Value val) {
this.val = val;
}
#Override
public Value getValue() {
return val;
}
}
package dk.asj.variables;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class CompoundVariable extends VariableBase {
final List<VariableBase> children = new LinkedList<VariableBase>();
public void addChild(final VariableBase c) {
children.add(c);
}
#Override
protected void internalSetValue(final Value val) {
for (int i = 0; i < val.getCompositeValue().size(); ++i) {
children.get(i).setValue(val.getCompositeValue().get(i));
}
}
#Override
public Value getValue() {
final List<Value> res = new ArrayList<Value>(children.size());
for (final VariableBase var : children) {
res.add(var.getValue());
}
return new Value() {
#Override
public int getIntValue() {
throw new RuntimeException("This is a composite value");
}
#Override
public String getStringValue() {
throw new RuntimeException("This is a composite value");
}
#Override
public List<Value> getCompositeValue() {
return res;
}
};
}
}
I'm not sure if this answers your question, however, this could lead to some new ideas, here is what I came up with in a similar situation:
I named these DynamicVariables. A dynamic variable may have a default value or be evaluated by a lamda (Java 8)/anonymous inner class (pre-Java 8).
Each variable has an evaluation context and can be evaluated only in a context - i.e. Session context or a Global context. Contexts fallback to each other and create an hierarchy, i.e. Session context falls back to a Global context. So the default variable constant or lambda value can be shadowed by a lambda or a constant defined in a context. In instance, session-scoped variables shadow out global vars when are accessed inside a session.
And this appeared to be quite a flexible approach - I even implemented a trivial dependency injection by introducing InjectionContext which is a thread-safe context holding an object being wired.
You might want to have a look at an example of how this is used in a deployment tool I'm currently developing. Configuration management and shared application logic there is built upon these variables. Code is under bear.context package, but it's rather raw at the moment.

Generic OR instead of AND <T extends Number | CharSequence>

Is it possible to generically parameterize a method accepting EITHER ClassA OR InterfaceB ?
Does Not Compile Due to | Pseudocode
public <T extends Number | CharSequence> void orDoer(T someData){ // ... }
i.e. instead of writing multiple method signatures, I would like this one method to accept either a Number or CharSequence as an argument
Should Pass with a Number OR CharSequence argument
orDoer(new Integer(6));
int somePrimitive = 4;
orDoer(somePrimitive);
orDoer("a string of chars");
If you really want to do that, you'll need to wrap youur accepted classes inside a custom class of your own. In your example case, probably something like:
public class OrDoerElement {
private final Number numberValue;
private final CharSequence charSequenceValue;
private OrDoerElement(Number number, CharSequence charSequence) {
this.numberValue = number;
this.charSequenceValue = charSequence;
}
public static OrDoerElement fromCharSequence(CharSequence value) {
return new OrDoerElement(null, value);
}
public static OrDoerElement fromNumber(Number value) {
return new OrDoerElement(value, null);
}
}
And your orDoer method becomes:
public void orDoer(OrDoerElement someData) { .... }
Then you can build one of those and use in your method using either:
orDoer(OrDoerElement.fromCharSequence("a string of chars"));
orDoer(OrDoerElement.fromNumber(new Integer(6)));
But honestly, that sounds a bit too complex and too much work just to be able to call a method with different parameter types. Are you sure you can't achieve the same using two methods, and a third method for the common logic?
Is using an anonymous abstract class an option for you? When I need type safe parameters or return types, I use some variant of the code below. That being said, I agree with the other comments here, and am curious what benefit you really derive when you're enforcing a type safety for a group of objects that don't have all that much in common.
public abstract class Doer<T> {
public void do(T obj) {
// do some stuff.
}
}
// calling method
new Doer<Number>(){}.do(new Integer(5));
For the original question:
public void orDoer(Object someData){
assert someData instanceof Number || someData instanceof CharSequence;
// ...
}
In your more specific case, the assert statement should just use introspection to clarify if the object has the specifics you want, i.e. check for a constructor from String, probe to create a new instance of the object from the toString() result of the incoming object, and compare both for equality:
public void orDoer(Object someData) {
assert isUniconstructable(someData);
}
public static boolean isUniconstructable(Object object) {
try {
return object.equals(object.getClass().getConstructor(String.class)
.newInstance(object.toString()));
} catch (InstantiationException | IllegalAccessException | InvocationTargetException
| NoSuchMethodException| RuntimeException e) {
return false;
}
}
(Because of the exceptions that may be thrown, we need to wrap the assert test into its own function.)
Be aware that introspection may break due to Android’s ProGuard code compression which rewrites the class names, and instead of YourClass just a Class, i.e. Q, is stored in the database, and when you want to restore it with a later version of your app which has more classes, class Q is something different then. See the ProGuard website for more information on this; I just wanted to notify that you should be aware of this when using introspection on Android.

Avoiding instanceof in Java

Having a chain of "instanceof" operations is considered a "code smell". The standard answer is "use polymorphism". How would I do it in this case?
There are a number of subclasses of a base class; none of them are under my control. An analogous situation would be with the Java classes Integer, Double, BigDecimal etc.
if (obj instanceof Integer) {NumberStuff.handle((Integer)obj);}
else if (obj instanceof BigDecimal) {BigDecimalStuff.handle((BigDecimal)obj);}
else if (obj instanceof Double) {DoubleStuff.handle((Double)obj);}
I do have control over NumberStuff and so on.
I don't want to use many lines of code where a few lines would do. (Sometimes I make a HashMap mapping Integer.class to an instance of IntegerStuff, BigDecimal.class to an instance of BigDecimalStuff etc. But today I want something simpler.)
I'd like something as simple as this:
public static handle(Integer num) { ... }
public static handle(BigDecimal num) { ... }
But Java just doesn't work that way.
I'd like to use static methods when formatting. The things I'm formatting are composite, where a Thing1 can contain an array Thing2s and a Thing2 can contain an array of Thing1s. I had a problem when I implemented my formatters like this:
class Thing1Formatter {
private static Thing2Formatter thing2Formatter = new Thing2Formatter();
public format(Thing thing) {
thing2Formatter.format(thing.innerThing2);
}
}
class Thing2Formatter {
private static Thing1Formatter thing1Formatter = new Thing1Formatter();
public format(Thing2 thing) {
thing1Formatter.format(thing.innerThing1);
}
}
Yes, I know the HashMap and a bit more code can fix that too. But the "instanceof" seems so readable and maintainable by comparison. Is there anything simple but not smelly?
Note added 5/10/2010:
It turns out that new subclasses will probably be added in the future, and my existing code will have to handle them gracefully. The HashMap on Class won't work in that case because the Class won't be found. A chain of if statements, starting with the most specific and ending with the most general, is probably the best after all:
if (obj instanceof SubClass1) {
// Handle all the methods and properties of SubClass1
} else if (obj instanceof SubClass2) {
// Handle all the methods and properties of SubClass2
} else if (obj instanceof Interface3) {
// Unknown class but it implements Interface3
// so handle those methods and properties
} else if (obj instanceof Interface4) {
// likewise. May want to also handle case of
// object that implements both interfaces.
} else {
// New (unknown) subclass; do what I can with the base class
}
You might be interested in this entry from Steve Yegge's Amazon blog: "when polymorphism fails". Essentially he's addressing cases like this, when polymorphism causes more trouble than it solves.
The issue is that to use polymorphism you have to make the logic of "handle" part of each 'switching' class - i.e. Integer etc. in this case. Clearly this is not practical. Sometimes it isn't even logically the right place to put the code. He recommends the 'instanceof' approach as being the lesser of several evils.
As with all cases where you are forced to write smelly code, keep it buttoned up in one method (or at most one class) so that the smell doesn't leak out.
As highlighted in the comments, the visitor pattern would be a good choice. But without direct control over the target/acceptor/visitee you can't implement that pattern. Here's one way the visitor pattern could possibly still be used here even though you have no direct control over the subclasses by using wrappers (taking Integer as an example):
public class IntegerWrapper {
private Integer integer;
public IntegerWrapper(Integer anInteger){
integer = anInteger;
}
//Access the integer directly such as
public Integer getInteger() { return integer; }
//or method passthrough...
public int intValue() { return integer.intValue(); }
//then implement your visitor:
public void accept(NumericVisitor visitor) {
visitor.visit(this);
}
}
Of course, wrapping a final class might be considered a smell of its own but maybe it's a good fit with your subclasses. Personally, I don't think instanceof is that bad a smell here, especially if it is confined to one method and I would happily use it (probably over my own suggestion above). As you say, its quite readable, typesafe and maintainable. As always, keep it simple.
Instead of a huge if, you can put the instances you handle in a map (key: class, value: handler).
If the lookup by key returns null, call a special handler method which tries to find a matching handler (for example by calling isInstance() on every key in the map).
When a handler is found, register it under the new key.
This makes the general case fast and simple and allows you to handle inheritance.
You can use reflection:
public final class Handler {
public static void handle(Object o) {
try {
Method handler = Handler.class.getMethod("handle", o.getClass());
handler.invoke(null, o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void handle(Integer num) { /* ... */ }
public static void handle(BigDecimal num) { /* ... */ }
// to handle new types, just add more handle methods...
}
You can expand on the idea to generically handle subclasses and classes that implement certain interfaces.
I think that the best solution is HashMap with Class as key and Handler as value. Note that HashMap based solution runs in constant algorithmic complexity θ(1), while the smelling chain of if-instanceof-else runs in linear algorithmic complexity O(N), where N is the number of links in the if-instanceof-else chain (i.e. the number of different classes to be handled). So the performance of HashMap based solution is asymptotically higher N times than the performance of if-instanceof-else chain solution.
Consider that you need to handle different descendants of Message class differently: Message1, Message2, etc. . Below is the code snippet for HashMap based handling.
public class YourClass {
private class Handler {
public void go(Message message) {
// the default implementation just notifies that it doesn't handle the message
System.out.println(
"Possibly due to a typo, empty handler is set to handle message of type %s : %s",
message.getClass().toString(), message.toString());
}
}
private Map<Class<? extends Message>, Handler> messageHandling =
new HashMap<Class<? extends Message>, Handler>();
// Constructor of your class is a place to initialize the message handling mechanism
public YourClass() {
messageHandling.put(Message1.class, new Handler() { public void go(Message message) {
//TODO: IMPLEMENT HERE SOMETHING APPROPRIATE FOR Message1
} });
messageHandling.put(Message2.class, new Handler() { public void go(Message message) {
//TODO: IMPLEMENT HERE SOMETHING APPROPRIATE FOR Message2
} });
// etc. for Message3, etc.
}
// The method in which you receive a variable of base class Message, but you need to
// handle it in accordance to of what derived type that instance is
public handleMessage(Message message) {
Handler handler = messageHandling.get(message.getClass());
if (handler == null) {
System.out.println(
"Don't know how to handle message of type %s : %s",
message.getClass().toString(), message.toString());
} else {
handler.go(message);
}
}
}
More info on usage of variables of type Class in Java: http://docs.oracle.com/javase/tutorial/reflect/class/classNew.html
You could consider the Chain of Responsibility pattern. For your first example, something like:
public abstract class StuffHandler {
private StuffHandler next;
public final boolean handle(Object o) {
boolean handled = doHandle(o);
if (handled) { return true; }
else if (next == null) { return false; }
else { return next.handle(o); }
}
public void setNext(StuffHandler next) { this.next = next; }
protected abstract boolean doHandle(Object o);
}
public class IntegerHandler extends StuffHandler {
#Override
protected boolean doHandle(Object o) {
if (!o instanceof Integer) {
return false;
}
NumberHandler.handle((Integer) o);
return true;
}
}
and then similarly for your other handlers. Then it's a case of stringing together the StuffHandlers in order (most specific to least specific, with a final 'fallback' handler), and your despatcher code is just firstHandler.handle(o);.
(An alternative is to, rather than using a chain, just have a List<StuffHandler> in your dispatcher class, and have it loop through the list until handle() returns true).
Just go with the instanceof. All the workarounds seem more complicated. Here is a blog post that talks about it: http://www.velocityreviews.com/forums/t302491-instanceof-not-always-bad-the-instanceof-myth.html
I have solved this problem using reflection (around 15 years back in pre Generics era).
GenericClass object = (GenericClass) Class.forName(specificClassName).newInstance();
I have defined one Generic Class ( abstract Base class). I have defined many concrete implementations of base class. Each concrete class will be loaded with className as parameter. This class name is defined as part of configuration.
Base class defines common state across all concrete classes and concrete classes will modify the state by overriding abstract rules defined in base class.
At that time, I don't know the name of this mechanism, which has been known as reflection.
Few more alternatives are listed in this article : Map and enum apart from reflection.
Add a method in BaseClass which returns name of the class. And override the methods with the specific class name
public class BaseClass{
// properties and methods
public String classType(){
return BaseClass.class.getSimpleName();
}
}
public class SubClass1 extends BaseClass{
// properties and methods
#Override
public String classType(){
return SubClass1.class.getSimpleName();
}
}
public class SubClass2 extends BaseClass{
// properties and methods
#Override
public String classType(){
return SubClass1.class.getSimpleName();
}
}
Now use the switch case in following way-
switch(obj.classType()){
case SubClass1:
// do subclass1 task
break;
case SubClass2:
// do subclass2 task
break;
}
What I use for Java 8:
void checkClass(Object object) {
if (object.getClass().toString().equals("class MyClass")) {
//your logic
}
}

Categories