The Artima Developer Community
Sponsored Link

Java Buzz Forum
It Is Generic After All

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Weiqi Gao

Posts: 1808
Nickname: weiqigao
Registered: Jun, 2003

Weiqi Gao is a Java programmer.
It Is Generic After All Posted: Oct 11, 2004 8:32 PM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Weiqi Gao.
Original Post: It Is Generic After All
Feed Title: Weiqi Gao's Weblog
Feed URL: http://www.weiqigao.com/blog/rss.xml
Feed Description: Sharing My Experience...
Latest Java Buzz Posts
Latest Java Buzz Posts by Weiqi Gao
Latest Posts From Weiqi Gao's Weblog

Advertisement

Bruce Eckel, March 10, 2004: Generics Aren't

Bruce Eckel, October 8, 2004: ... Using adapters like this would seem to compensate for the lack of latent typing, and thus allow you to write genuinely generic code.

From it's announcement in June 1998, to the final induction into Java 5.0 in August 2004, Java generics has gone through over six years of maturation.

Originally hailed as an efficient and backward compatible extension to the JDK rooted in some esoteric theory, Java generics, especially its erasure based implementation has been under much criticism lately (including on this blog).

One of the complaints leveled against Java generics is that it is not generic:

public class CallF {
  public <T> void callF(T t) {
    t.f();  // can't call f() here
  }
}

In his latest weblog, Bruce Eckel offers several ways around the problem by using adapters. One of them, termed surprising by Bruce, uses an abstract generic adapter instantiated and anonymously extended at the call site.

Here's a distilled version of the example:

[weiqi@gao] $ cat A.java
public class A {
  public void f() {
    System.out.println("A.f()");
  }
}

[weiqi@gao] $ cat CallF.java
public class CallF {
  public <T> void callF(HasF<T> adapter) {
    adapter.f();
  }
}

[weiqi@gao] $ cat HasF.java
public abstract class HasF<T> {
  protected T t;
  public HasF(T t) {
    this.t = t;
  }
  public abstract void f();
}

[weiqi@gao] $ cat Main.java
public class Main {
  public static void main(String[] args) {
    A a = new A();
    CallF f = new CallF();
    f.callF(new HasF<A>(a) {
      public void f() {
        t.f();  // OK to call f() since t is of type A here
      }
    });
  }
}

[weiqi@gao] $ javac *.java

[weiqi@gao] $ java Main
A.f()

Once understood, the code is quite clear.

The classes CallF and HasF is the library that just want to call a method named f(). No extra requirement is placed on T except that it has the f() method. This qualifies them as true generic algorithm classes.

The class A is a POJO that has an f() method.

In Main we manage to hook up the "library" and the POJO and have the "library", which knows nothing about the POJO, call a method on the POJO, which knows nothing about the "library", just like in C++. Great!

Looking back at the solution, I can't help but notice all the clutter. Suddenly the irony is apparent: We went all the way to add generics into Java, ostensibly to simplify our Java code, yet at the end our code is even more cluttered.

Could we have done the same thing without generics? Of course. This is the land of erasure. Decompiling the classes with JODE, I get:

[weiqi@gao] $ jode -d jode A CallF HasF Main
Jode (c) 1998-2001 Jochen Hoenicke <jochen@gnu.org>
A
CallF
HasF
Main
 
Decompiled 4 classes.

[weiqi@gao] $ cd jode/

[weiqi@gao] $ cat A.java CallF.java HasF.java Main.java

public class A
{
    public void f() {
        System.out.println("A.f()");
    }
}
 
public class CallF
{
    public void callF(HasF hasf) {
        hasf.f();
    }
}
 
public abstract class HasF
{
    protected Object t;
     
    public HasF(Object object) {
        t = object;
    }
     
    public abstract void f();
}
 
public class Main
{
    public static void main(String[] strings) {
        A a = new A();
        CallF callf = new CallF();
        callf.callF(new HasF(a) {
            public void f() {
                ((A) t).f();
            }
        });
    }
}

[weiqi@gao] $ javac *.java

[weiqi@gao] $ java Main
A.f()

Comparing this with the generic classes, we discover that all of our generics mumbo-jumbo bought us exactly one puny little cast!.

Oh wait a minute, have I just written a genuinely generic algorithm in pre 5.0 Java without using generics?

Interesting!

Read: It Is Generic After All

Topic: [Sep 30, 2004 06:42 PDT] 2 Links Previous Topic   Next Topic Topic: New T-Shirt Idea

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use