Question

I just recently heard of duck typing and I read the Wikipedia article about it, but I'm having a hard time translating the examples into Java, which would really help my understanding.

Would anyone be able to give a clear example of duck typing in Java and how I might possibly use it?

Was it helpful?

Solution

Java is by design not fit for duck typing. The way you might choose to do it is reflection:

public void doSomething(Object obj) throws Exception {

    obj.getClass().getMethod("getName", new Class<?>[] {}).invoke(obj);
}

But I would advocate doing it in a dynamic language, such as Groovy, where it makes more sense:

class Duck {
    quack() { println "I am a Duck" }
}

class Frog {
    quack() { println "I am a Frog" }
}

quackers = [ new Duck(), new Frog() ]
for (q in quackers) {
    q.quack()
}

Reference

OTHER TIPS

See this blog post. It gives a very detailed account of how to use dynamic proxies to implement duck typing in Java.

In summary:

  • create an interface that represents the methods you want to use via duck typing
  • create a dynamic proxy that uses this interface and an implementation object that invokes methods of the interface on the underlying object by reflection (assuming the signatures match)

check this library:

interface MyInterface {
    void foo();
    int bar(int x, int y);
    int baz(int x);
}

public class Delegate {
    public int bar() {
        return 42;
    }
}

DuckPrxy duckProxy = new DuckPrxyImpl();
MyInterface prxy = duckProxy.makeProxy(MyInterface.class, new Delegate());
prxy.bar(2, 3); // Will return 42.

With an interface duck typing is simple using a Dynamic Proxy, you should match the method name and return type.

Java doesn't implement duck typing.

With java 8, you have 2 ways:

nº1: if you only need one method, use lambdas

static interface Action { public int act(); }

public int forEachAct(List<Action> actionlist) {
   int total = 0;
   for (Action a : actionList)
       total += a.act();
}

public void example() {
    List<Action> actionList = new ArrayList<>();
    String example = "example";
    actionList.add(example::length);
    forEachAct(actionList);
}

nº2: Use anonymous classes (not very performance-wise, but in some non-critical parts it can be done)

static interface Action {
    public int act();
    public String describe();
}

public void example() {
    List<Action> actionList = new ArrayList<>();
    String example = "example";

    actionList.add(new Action(){
        public int act() { return example.length(); }
        public String describe() { return "Action: " + example; }
    });
}

Typing in Java is nominal - compatibility is based on names. If you need an examples on how duck-typing (or structural typing) may look like in Java please look at this page: http://whiteoak.sourceforge.net/#Examples which provides examples for program written in Whiteoak: A Java-compatible language that also supports structural typing.

Typically, duck typing is used with dynamically typed languages. You would check at runtime for the existence of methods or properties that are required to fulfill your needs, regardless of inheritance hierarchies.

Other than using reflection, which would get ugly, the closest you can get is by using minimal interfaces that match the criteria of what you would need for duck typing. This blog post does a good job describing the concept. It loses much of the simplicity of duck typing in python or ruby or javascript, but its actually pretty good practice in Java if you're looking for a high level of reusability.

Nice definition:

Objects are polymorphic without being related by a common base class or interface.

Reference

I've written a utility class to dynamically create decorators for an object. You could use it for duck typing: https://gist.github.com/stijnvanbael/5965616

Example:

interface Quacking {
    void quack();
}

class Duck {
    public void quack() { System.out.println("Quack!"); }
}

class Frog {
    public void quack() { System.out.println("Ribbip!"); }
}

Quacking duck = Extenter.extend(new Duck()).as(Quacking.class);
Quacking frog = Extenter.extend(new Frog()).as(Quacking.class);

duck.quack();
frog.quack();

Output:

Quack!
Ribbip!

Late to the party (as usual), but I wrote a quick class for doing some duck typing myself. See here.

It will only go to interfaces, but for a usage example:

interface Bird {
    void fly();
}

interface Duck extends Bird {
    void quack();
}

class PseudoDuck {
    void fly() {
        System.out.println("Flying");
    }

    void quack() {
        System.out.println("Quacking");
    }
}

class Tester {
    @Test
    void testDuckTyping() {
        final Duck duck
                = DuckTyper.duckType(new PseudoDuck(), Duck.class);
    }
}

Supports default interface methods, parameters, checking Exception types are compatible and will check all methods of the PseudoDuck's class (including private). Haven't done any testing with generic interfaces yet though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top