Home » Java » Enterprise Java » Dynamic casting in Java

About Nicolas Frankel

Nicolas Frankel
Developer Advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). Usually working on Java/Java EE and Spring technologies, but with narrower interests like Software Quality, Build Processes and Rich Internet Applications. Currently working for Exoscale. Also double as a teacher in universities and higher education schools, a trainer and triples as a book author.

Dynamic casting in Java

I’m a big fan of Baeldung’s blog. One of his previous post is about casting in Java. Unfortunately, I feel it misses one important point: dynamic casting. Since that’s is (very) relatively new, this post will try to fill that gap.

Do not use casting

The first thing is that it should be relatively easy to avoid casting.

Using polymorphism

Polymorphism is a great way not to cast. Consider the following code:

List animals = new ArrayList();
animals.add(new Cat());
animals.add(new Dog());
for (Animal animal: animals) {
    if (animal instanceof Cat) {
        ((Cat) animal).mew();
    } else if (animal instanceof Dog) {
        ((Dog) animal).bark();
    } else if (animal instanceof Snake) {
        ((Snake) animal).hiss();
    }
}

If all object types in the collection inherit from a single type, it’s possible to use polymorphism. Just add one method in this single type and override it in the subtypes.

public abstract class Animal {
    public abstract void makeSound();
}

public class Dog {
    @Override public void makeSound() {
        bark();
    }
}

public class Cat {
    @Override public void makeSound() {
        mew();
    }
}

Using generics

Polymorphism cannot be always applied. For example, this is the case when:

  • Items are not instances of related type
  • The parent type is not within our control sphere
  • etc.

In those cases, generics is another way to avoid casting.

Before Java 5, the following code would be the norm:

List dates = new ArrayList();
dates.add(new Date());
Object object = dates.get(0);
Date date = (Date) object;

On line 4, casting required. Though the runtime type is Date, the compiler has no way to know about it.

With generics, the above code can be rewritten:

List<Date> dates = new ArrayList<>();
dates.add(new Date());
Date date = dates.get(0);

On line 3, no casting is required: the compiler has enough information thanks to generics.

When casting is mandatory

Despite to what some fanatics think, it happens that sometimes casting cannot be ignored.

One such use-case is the Servlet API. Map storing objects in servlet context/request/session do not use generics. And even if they did, they would be using Object.

// In a servlet
ServletContext context = getServletContext();
context.put("date", new Date());

// Somewhere else
ServletContext context = getServletContext();
Object object = context.get("date");
Date date = (Date) object;

Dynamic casting

The only form of casting originally available was static casting. Which means the casting type needs to be known at compile time. For example, let’s imagine a method that accepts a Stream<Object>, filters all element of a certain type and returns those elements in the right type. This is an example of the usage:

List<?> items = ...
List dates = filter(Date.class, items);

There’s no way to implement the filter method with static casting. There are actually two issues:

  1. The instanceof operator requires a type, not a Class instance e.g. item instanceof Date
  2. The cast syntax as well e.g. (Date) item

The instanceof operator can be replaced with a call to Class.isInstance(Object)(since JDK 1.1). This is quite well-known, if not widely used.

The API to replace the cast syntax, however, is much more “recent”. There’s a Class.cast(Object) method since JDK 1.5 It is a simple wrapper around the legacy syntax.

Using both methods, it’s finally possible to implement the filter method above.

static  List filter(Class clazz, List<?> items) {
    return items.stream()
        .filter(clazz::isInstance)
        .map(clazz::cast)
        .collect(Collectors.toList());
}

Using the casting API allows dynamic casting. Without it, it’s not possible to implement the above method.

Conclusion

Despite what many people outside the ecosystem think, Java evolves, even if not very fast. However, developers needs to be acquainted with the new capabilities offered by each version.

To go further:

Published on Java Code Geeks with permission by Nicolas Frankel, partner at our JCG program. See the original article here: Dynamic casting in Java

Opinions expressed by Java Code Geeks contributors are their own.

(0 rating, 0 votes)
You need to be a registered member to rate this.
Start the discussion Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of