Basically, you check if an object is an instance of a specific class. You normally use it, when you have a reference or parameter to an object that is of a super class or interface type and need to know whether the actual object has some other type (normally more concrete).
Example:
public void doSomething(Number param) {
if( param instanceof Double) {
System.out.println("param is a Double");
}
else if( param instanceof Integer) {
System.out.println("param is an Integer");
}
if( param instanceof Comparable) {
//subclasses of Number like Double etc. implement Comparable
//other subclasses might not -> you could pass Number instances that don't implement that interface
System.out.println("param is comparable");
}
}
Note that if you have to use that operator very often it is generally a hint that your design has some flaws. So in a well designed application you should have to use that operator as little as possible (of course there are exceptions to that general rule).
Answer from Thomas on Stack Overflowinstanceof - concept does not match actual use
programming practices - Replacement for instanceof Java? - Software Engineering Stack Exchange
inheritance - Java instanceof and Clean architecture - Software Engineering Stack Exchange
[Java] How to get around using instanceof?
Videos
Basically, you check if an object is an instance of a specific class. You normally use it, when you have a reference or parameter to an object that is of a super class or interface type and need to know whether the actual object has some other type (normally more concrete).
Example:
public void doSomething(Number param) {
if( param instanceof Double) {
System.out.println("param is a Double");
}
else if( param instanceof Integer) {
System.out.println("param is an Integer");
}
if( param instanceof Comparable) {
//subclasses of Number like Double etc. implement Comparable
//other subclasses might not -> you could pass Number instances that don't implement that interface
System.out.println("param is comparable");
}
}
Note that if you have to use that operator very often it is generally a hint that your design has some flaws. So in a well designed application you should have to use that operator as little as possible (of course there are exceptions to that general rule).
instanceof is used to check if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.
Read more from the Oracle language definition here.
Hello,
It is my understanding that the instanceof keyword is used to determine whether an object instance is in the inheritance hierarchy of a class/interface, ex. earth instanceof Planet. This returns a boolean. Easy enough to understand.
Why does the compiler throw a fit if I use instanceof on an object instance that isn't in the inheritance hierarchy? Ex. dog instanceof Planet. If it doesn't allow testing of unrelated objects, what is the point? It should just return false in this example according to what I've gathered. But if the compiler mandates that the two things are related in the first place, instanceof would always return true. Not sure what I'm not understanding.
I've read a few things dissuading the use of instanceof altogether because it reflects poor OO design so I don't plan to actually use it much if at all, but want to deepen my understanding of Java and I haven't found an explanation of the contradiction above yet.
Thanks in advance.
The reason instanceof is discouraged is that it's not OOP.
There should be no reason for the caller/user of an object to know which concrete class it is an instance of beyond which type the variable it is declared as.
If you need different behavior in subclasses add a method and implement them differently.
instanceof isn't necessarily a bad thing, however it is something that one should look at.
An example of where it works correctly is in a place where one gets a collection of the base type and you only want the ones of a subtype. Getting the network addresses from NetworkInterface.getNetworkInterfaces() returns back NetworkInterface objects which have a collection of InetAddress objects, some of which are Inet4Address and some are Inet6Address. If one wants to filter the collection for Inet4Address objects, it is necessary to use instanceof.
In the situation that is being described in the original post, there is a Base class, something that extends that base class and something that extends the extended class. While not completely informative, this seems to have the underpinnings of some less than ideal design.
When you are returning a base class unless there is good reason for it being designed that way (backwards compatibility between specifications of an earlier version) you shouldn't be trying to peek at the underlying types. If you are returned a Set, you know you are getting a set. It allows the developer to later change his or her mind to return a more specific type (SortedSet) or change the underlying type (HashSet to TreeSet) without breaking anything.
Reconsider your design of how the objects are structured and parented to see if one can make an better class model that is doesn't require a distinction of types.
If you want to add a method to a class hierarchy without actually adding the method, consider the Visitor Pattern. You could create a validation visitor, and let each entity select the appropriate method of the visitor.
First, your ParentEntity class hierarchy would need a bit of boilerplate to support visitors:
interface EntityVisitor<T> {
T visitA(AEntity a);
T visitB(BEntity b);
}
class ParentEntity {
<T> T accept(EntityVisitor<T> v);
}
class EntityA extends ParenEntity {
...
@Override <T> T accept(EntityVisitor<T> v) {
return v.visitA(this);
}
}
Next, we can implement and use a visitor that performs validation.
class Validation implements EntityVisitor<Void> {
EntityRepository repository;
...
@Override Void visitA(AEntity a) { ... }
@Override Void visitB(BEntity b) { ... }
}
class EntityRepository ... {
void save(List<ParentEntity> list) {
list.ForEach(e -> {
e.accept(new Validation(this));
...
});
}
}
The validation visitor can have access to both the entity and the repository (in order to make further queries), and will therefore be able to perform the full validation.
Using such a pattern has advantages and disadvantages compared to an instanceof check and compared to moving the validation logic into the entities.
An instanceof is a much simpler solution, especially if you only have very few entity types. However, this could silently fail if you add a new entity type. In contrast, the visitor pattern will fail to compile until the accept() method is implemented in the new entity. This safety can be valuable.
While this pattern ends up having the same behaviour as adding a validate() method to the entities, an important difference is where that behaviour is located and how our dependency graph looks. With a validate() method, we would have a dependency from the entities to the repository, and would have referential integrity checks intermixed with actual business logic. This defeats the point of an Onion Architecture. The visitor pattern lets us break this dependency and lets us keep the validation logic separate from other business logic. The cost of this clearer design structure is extra boilerplate in the form of the EntityVisitor interface and the accept() method that must be added to all entities in the relevant class hierarchy.
Whether these trade-offs are worth it is your call. You know your codebase best, and you have the best idea how it might evolve.
However, performing validation based on the result of multiple queries can lead to data integrity problems. The repository should either make sure to use database transactions (and offer an API that clearly communicates when modifications have been committed), or the relevant integrity checks should be done within the database, e.g. using constraints in an SQL database. In some cases, the validation checks can also be expressed as part of an insert or update query.
I know what I am about to answer is not exactly good practice but if you want to avoid instanceof's and have a generic way to call the respective method for that subclass you could use reflection:
Method m = EntityRepository.class.getMethod("validate", e.getClass());
m.invoke(this, e);
Of course, this will have a negative effect on performance and in some ways maintainability (with the only upside being less code).
Regarding the performance overhead, you can somewhat mitigate it by loading all the methods at startup:
Map<Class<?>, Method> methods = new HashMap<>();
Reflections reflections = new Reflections(ParentEntity.class, new SubTypesScanner());
Set<Class<? extends Animal>> subclasses = reflections.getSubTypesOf(ParentEntity .class);
for (Class<?> c : subclasses) {
methods.put(c, Solution.class.getMethod("makeTalk",c));
}
Where Reflections comes from the Reflections library
And then just call the method using:
methods.get(e.getClass()).invoke(this, e)
I may need to redesign a portion of a project I'm working on. I've read that it's generally bad practice to use the instanceof operator, and the only solution I have seen that gets around it is the visitor design pattern, which seems unnecessarily complicated. Situation:
I have a collection of Job objects. Each Job has 4 lists of various tasks that are read in at runtime during the Job creation. The tasks share a common interface, and there are 4 flavors of Task. For simplicity, I'm using TaskType1, TaskType2, etc.
The Job class has the following methods that add the tasks to the appropriate list:
void addTaskType1(TaskType1 task){
taskType1List.add(task);
}There is one method for each type of task. I have a TaskFactory which returns the appropriate task type during Job creation. So, my parsing object reads a task, sends the type description to the factory, which returns the appropriate type of Task.
What I currently have to do to add the Task to the correct list is as follows:
Task returnedTask = taskFactory.createTask(taskType);
if(returnedTask instance of TaskType1){
job.addTaskType1(returnedTask);
}
else if(returnedTask instanceof TaskType2) and so on ....Is there a better approach? It feels wrong to do it this way.
There was a similar question posted here before that said having multiple lists was probably the wrong way to approach the problem, but I haven't been able to locate that post for more suggestions. Thanks for any help.
For example, I have an arrayList called a and a String called b
Typing boolean x = a instanceof String; just gives an error that says java: incompatible types: ArrayList cannot be converted to String...am I using this incorrectly somehow?
This is the definition of reflection according to wikipedia:
In computer science, reflection is the process by which a computer program can observe (do type introspection) and modify its own structure and behavior at runtime.
I couldn't have said it better myself and highlighted the important part for your question. That said, yes, instanceof is considered using reflection. The program observes its structure and conducts type introspection.
For the sake of clarity, I would consider two answers.
Theoretically, instanceof is a form of reflection, as explained in Falcon's answer.
In computer science, reflection is the process by which a computer program can observe (do type introspection) and modify its own structure and behavior at runtime.
However, practically, when a programmer talks about using reflection he usually refers to much more than just checking whether a variable is of a certain type. This is such a rudimentary concept, without which, polymorphism wouldn't be possible.
Do note that using instanceof often indicates a code smell, and proper polymorphism can often be used instead.