Explain Codes LogoExplain Codes Logo

Polymorphism: Why use "List list = new ArrayList" instead of "ArrayList list = new ArrayList"?

java
interface
encapsulation
api-design
Anton ShumikhinbyAnton Shumikhin·Mar 2, 2025
TLDR

Use List list = new ArrayList(); to implement polymorphism, improving code adaptability and maintenance ease. When you use List, your code isn't tied to a specific class but instead, could easily switch between List types like LinkedList or Vector.

List<String> list = new ArrayList<>(); // You can swap ArrayList with LinkedList and code won't bat an eyelid! list.add("apple"); // Code is untouched by the sort of List implementation System.out.println(list.get(0)); // Outputs "apple", not a bug! Not always guaranteed ;)

Employing List keeps your code flexible, able to adapt to different List implementations without much fuss.

Driving with Interface

Committing to List list, you're hitching a ride with an interface rather than a concrete implementation. This decision steers your code down a road of bountiful benefits, essential in complex, large-scale applications.

Modular Architecture

Coding with interfaces constructs a modular architecture. Your components are connected by abstractions rather than details, distancing your code from tight coupling that could lead to brittle and difficult modifications.

Tuning the Performance

A List could wear the skin of an ArrayList, LinkedList or even a CopyOnWriteArrayList, each boasting unique performance traits. Choosing List keeps your doors open to swap implementations like swapping lanes when the traffic gets too heavy.

List<String> list = new ArrayList<>(); // Smooth sailing // *Time passes*... // Too many insertions causing traffic jam? Time to change lanes! list = new LinkedList<>();

The Maintenance Marvel

Interfaces like List lay the foundation for clean code that's simple to test, maintain, and scale. They equip you to build systems that are prepared for unexpected future changes, like suddenly needing new List implementations from later Java versions or third-party libraries.

Error Patrol

The List interface is a sort of guard against compile-time errors. If your List reference attempts an operation which is out of the List contract bounds, the compiler blows the whistle. In ArrayList, these mistakes may only appear at runtime, when it's riskier and more expensive to fix.

The Encapsulation and API conundrum

For a robust, user-friendly API, it's a good practice to use the List interface in method signatures. This promotes a healthy coding culture and offers API users the freedom to employ their preferred implementations.

Unified API design

Using List in APIs ensures a consistent look and feel. Method signatures tell us we're working with a collection and there's no need to exhibit every single type of ArrayList unless really required.

// "Insert your desire for freedom joke here" public List<String> getBestJokes(); // A "free" method, doesn't care about implementation

Relaxed Coupling

Interfaces help soften coupling, making our code less interdependent and easier to change or replace with alternate implementations.

Change? No problem!

Exposing the List in our APIs minimizes the impact of changes. The internals may change, but as long as the List contract is maintained, our clients can continue their tea party undisturbed!