Home > Software Development > Two Opposite Trends in Java Programming: Which Should You Go With?

Two Opposite Trends in Java Programming: Which Should You Go With?

March 24th, 2010 Leave a comment Go to comments

Java is a static typing language, meaning you have to define a type before you can use it and the compiler checks the types for you. Some people like the static typing and others don’t. People like it would like even more into the language. Some others would prefer less typing. The rest don’t have strong opinions and are OK with both.

In the last several years, we actually see two opposite trends in Java programming: stronger typing and weaker typing. This blog analyzes in depth why these two trends happened and what do they mean for you. 

Time to learn how to "Google" and manage your VMware and clouds in a fast and secure


Generics for Stronger Typing

Before 1.5, Java has a little gap in the typing. For example, the Java collection library could have type leaks. Let’s take a look at two methods of the type List, which is an interface:

public boolean add(Object o);
public Object get(int index);

The add() method takes an object of Object type, meaning you can put in anything as you want because in Java every object is type or subtype (directly or indirectly) of Object. When you get an item out from the list, you have an object typed as Object. In most cases, you cast it to a specific type like:

String str = (String) list.get(0);

Now, if the first object is not of String type or its subtype, you get ClassCastException.How to prevent this from happening?

In Java 1.5, generics feature was added into the language. It allows you to specify the type of the items in the container. In the above example, you would do like this:

List<String> list = new ArrayList<String>();
String str = list.get(0);

You don’t need to do conversation any more. If you get the typing wrong, the compiler would flag you with errors. Everything is just safer than before. The whole collection library was re-written to support Generics.

The problem is that you have to learn how to use the generics. And the code using generics doesn’t look as clean as before. More about the generics can be found here.

Dependency Injection (DI) for Weaker Typing

In a strong typing language like Java, once you put in code that involves the implementation types, then you establish the dependency on these implementation classes. The compiler would demand you to have them ready before you can compile the code.

This enforces the type safety, but at the same time limits the flexibility. In some cases like a framework, it doesn’t know what implementations will be there in the future.

That is where DI comes to play.

The DI is really for removing dependencies on specific implementations of interfaces so that you can switch among them on the fly without re-compiling the code. Note that, before this technique was called DI or Inverse of Control (IoC), it’s used in some tools like Eclipse for extensibility. The foundation for the DI is the Java reflection API.

There are several DI frameworks, the most famous of which is the Spring framework. While using Spring, you define an XML file, say “appcontext.xml,” which includes a bean definition like this:

<bean id="message" <strong>class</strong>="org.doublecloud.MessageImpl"  lazy-init="false" init-method="printSelf">
<property name="content" ref="stringmessage" />

In your code, you write something like that:

FileSystemXmlApplicationContext factory = <strong>new</strong> FileSystemXmlApplicationContext("applicationcontext.xml");
Message stm = (Message) factory.getBean("message");

Now you code compile without the presence of the MessageImpl class, and you can change the class in the XML file to whatever implementation class that implements the Message interface. The framework then just picks it up and makes it work.

All look great, right?

Coming along with the benefits are some drawbacks:

  1. If you miss type something especially the class name, you won’t know it until running it.
  2. If your MessageImpl does not implement the Message interface, you won’t know it neither until running it. From the xml file itself, you cannot tell it’s a requirement.

Combined together, typing is getting weaker with DI. You could have the IDE to do a little extra for you to have above checked for you. But still, it needs extra tooling and a different way to work on the issue.

Besides the above drawbacks, there are also extra problem with code browsing and debugging. When trying to look into the implementation class, you will need extra effort. First, you will find out the XML file in which the bean is defined. It’s straight forward in this small sample, but could be quite troublesome if the implementation class is “injected” somewhere else. Secondly, you need to find out the name of implementation class in the XML file. Lastly, you can search for the implementation class.

If you turn on debugger, you may be able to get the real type using inspector and jump to the step 3 directly. Still, it’s not as straight forward as normal.


Given these two opposite trends, what are you going to do with them?

In general, strong typing is a good thing. It can help you to catch problems early at development time. It becomes more important when your system scope becomes bigger. Although you can write unit test code, you should leverage the language features like generics as your first defense. The effort for using the Generics is mostly minimal.

To develop generic enabled libraries is another story – you will need extra efforts there. Overall, the chance for you to get there is pretty small. Before you ever think about that, you should ask yourself whether you can use something in the standard Java libraries. If you do, forget about inventing your own wheel.

For the DI, it all depends on what you want to do.

If you just design a typical application, I would suggest you to go straight forward without DI. But if you are working on a framework or application that requires extensibilities, DI is your friend; otherwise, it could complicate your application without clear benefits.

Like many other technologies, there is no strictly “good” or “bad” with stronger or weaker typing. It’s all about when and how you use them on what.

  1. March 25th, 2010 at 20:17 | #1

    Hi Steve,

    Nice blog. I’ve been reading your blog for a while and I had to comment about this post. If implemented correctly dependency injection should not hinder type safety. It might seem that because we tend to declare dependencies using XML files we lose the compiler checks but this is not true, as you said the IDE (Eclipse, IntelliJ, …) parses this XML and checks for types, hence enforcing strong typing: you cannot inject a class not implementing the required interface.
    Also, in Spring, you’re not supposed to access beans via the application context directly and cast them to an implementation. In an ideal dependency injection scenario, you never access that context. The beans/classes are injected by Spring through the setters/constructors:

    public class Bean1 {
    private Bean2 bean2;

    // This is called by Spring
    public void setBean2(Bean2 bean2) {
    this.bean2 = bean2;

    public void do() {
    // use bean2

    As far as browsing is concerned, all modern IDEs will detect that this class is a bean and let you browse back and forth between the class and the XML file.
    So really, there is no reason for not using both strong typing and dependency injection :-)

  2. March 27th, 2010 at 21:45 | #2

    Hi Chris,

    Thanks for the nice comment! You are right that one could achieve both the DI and type safety with helpers like IDE with extra plug-ins. This is however not built into the language itself, therefore the compiler cannot do it. In a large project, the build team is in charge of build and they don’t use IDEs mostly. If for whatever reason, someone tweak the code outside IDE, it might cause problems.

    Overall DI is an indirection which brings flexibility but also complexity. One has to make a judgment whether the flexibility is really needed at the price to take care of extra complexity.


  1. No trackbacks yet.