Re: How to know which interfaces an object implements?

Discussion in 'Java' started by Thomas Weidenfeller, Oct 20, 2005.

  1. Miguel Farah wrote:
    > I'm writing a method that will receive as an argument an object (any
    > object) and does some stuff depending on which class it belongs to or
    > which interface it implements (in particular, wether it implements the
    > java.util.List interface).


    First of all, basing an application on such a design is a very bad idea
    without having a very, very good reason. The real solution would be to
    get rid of this stuff.

    Second, if you need to test for the presence of an interface, simply use
    instanceof:


    > Vector v=new Vector();


    if(v instanceof List) {
    List l = (List)v;
    ...
    }

    > if (v.getClass().getName().equals("java.util.Vector") { ....}


    if(c instanceof Vector) {
    ...
    }

    But as a rule, whenever you need stuff like instanceof, consider
    changing your design. This is just glue which is useful to link things
    together with don't fit. Which is fine, if you have no control over the
    things which you need to glue together (e.g. external libraries), but
    which is bad if you have designed your own stuff in a way that it
    doesn't fit together.

    /Thomas
    --
    The comp.lang.java.gui FAQ:
    ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
    http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/
    Thomas Weidenfeller, Oct 20, 2005
    #1
    1. Advertising

  2. Thomas Weidenfeller

    Miguel Farah Guest

    Thomas Weidenfeller wrote:
    > Miguel Farah wrote:
    > > I'm writing a method that will receive as an argument an object (any
    > > object) and does some stuff depending on which class it belongs to or
    > > which interface it implements (in particular, wether it implements the
    > > java.util.List interface).

    >
    > First of all, basing an application on such a design is a very bad idea
    > without having a very, very good reason. The real solution would be to
    > get rid of this stuff.
    >[...]


    Thanks all for the help. Using the instanceof operator was easier and
    more straightforward than I gave credit to. Live and learn...

    Now, on WHY I'm doing this:

    I usually have to debug source code written by someone else, where
    faulty data provokes errors. Tracing those usually implies getting
    printouts of said data in a logfile, and then figure out the rest.
    Usually, the quickest way is to simply stick in a System.out.println()
    and execute... which leads to useless output like this example:

    String[] c={"Hello", "world!"};
    [...]
    System.out.println("data: <"+c+">");

    The result is...

    data: <[Ljava.lang.String;@16f0472>

    Certainly not very useful.

    So I wrote a method that would get in a String[] and spit back its
    entire content, like this:

    System.out.println("data: <"+contentsOf(c)+">");

    data: <{Hello, World!}>


    Afterwards, I thought it would be better to write a method that would
    be
    able to do the same with hashtables, vectors... hell, ANY object. So
    far, I've implemented arrays, hashtables and lists (because that's what
    I encounter all the time). I just hope I'm not reinventing the wheel...


    This method is part of a "String utilities" class we have here:


    static public String contentsOf(Object o) {
    String s="";

    if (o==null) {
    s="null";

    } else if (o.getClass().isArray()) {
    s="{";
    Object[] a=(Object[])o;
    for (int i=0; i<a.length; i++) {
    s+=contentsOf(a) + ((i==a.length-1)?"":", ");
    }
    s+="}";

    } else if (o instanceof java.util.List) {
    s+="[";
    List l=(List)o;
    for (int i=0;i<l.size();i++) {
    s+=contentsOf(l.get(i)) + ((i==l.size()-1)?"":", ");
    }
    s+="]";

    } else if (o instanceof java.util.Hashtable) {
    s+="{";
    Hashtable h=(Hashtable)o;
    for(Enumeration e=h.keys(); e.hasMoreElements(); ) {
    Object c=e.nextElement();

    s+=contentsOf(c)+"="+contentsOf(h.get(c))+(e.hasMoreElements()?",
    ":"");
    }
    s+="}";

    } else {
    s=o.toString();

    }
    return s;
    }
    Miguel Farah, Oct 20, 2005
    #2
    1. Advertising

  3. Miguel Farah wrote:
    > I usually have to debug source code written by someone else, where
    > faulty data provokes errors. Tracing those usually implies getting
    > printouts of said data in a logfile, and then figure out the rest.
    > Usually, the quickest way is to simply stick in a System.out.println()
    > and execute... which leads to useless output like this example:
    >
    > String[] c={"Hello", "world!"};
    > [...]
    > System.out.println("data: <"+c+">");
    >
    > The result is...
    >
    > data: <[Ljava.lang.String;@16f0472>
    >
    > Certainly not very useful.

    Indeed! Instead of this you can use:
    System.out.println("data: " + Arrays.asList(c));
    You'll get the result:
    data: [Hello, world!]
    >
    > So I wrote a method that would get in a String[] and spit back its
    > entire content, like this:
    >
    > System.out.println("data: <"+contentsOf(c)+">");
    >
    > data: <{Hello, World!}>
    >
    >
    > Afterwards, I thought it would be better to write a method that would
    > be
    > able to do the same with hashtables, vectors... hell, ANY object. So
    > far, I've implemented arrays, hashtables and lists (because that's what
    > I encounter all the time). I just hope I'm not reinventing the wheel...
    >

    Sorry, you *are* reinventing the wheel.
    AbstractCollection (the super-class of Vector and others), AbstractMap
    (the super-class of HashMap and others) and Hashtable have already very
    smart toString() methods doing what you want. These toString() methods
    are automatically called by System.out.println(...).
    For example:
    List list = new Vector();
    list.add("Hello"); list.add("world!");
    System.out.println("list: " + list);
    results in:
    list: {Hello, world!}

    Map map = new HashMap();
    map.put("a","Hello"); map.put("b","world!");
    System.out.println("map: " + map);
    results in:
    map: {a=Hello, b=world!}

    --
    "Thomas:Fritsch$ops:de".replace(':','.').replace('$','@')
    Thomas Fritsch, Oct 20, 2005
    #3
  4. Thomas Weidenfeller

    Miguel Farah Guest

    Thomas Fritsch wrote:
    > Miguel Farah wrote:
    > > I usually have to debug source code written by someone else, where
    > > faulty data provokes errors. Tracing those usually implies getting
    > > printouts of said data in a logfile, and then figure out the rest.
    > > Usually, the quickest way is to simply stick in a System.out.println()
    > > and execute... which leads to useless output like this example:
    > >
    > > String[] c={"Hello", "world!"};
    > > [...]
    > > System.out.println("data: <"+c+">");
    > >
    > > The result is...
    > >
    > > data: <[Ljava.lang.String;@16f0472>
    > >
    > > Certainly not very useful.

    > Indeed! Instead of this you can use:
    > System.out.println("data: " + Arrays.asList(c));
    > You'll get the result:
    > data: [Hello, world!]



    That's indeed better, but still not enough to satisfy my convoluted
    mind. :) Please see the examples below.


    > > So I wrote a method that would get in a String[] and spit back its
    > > entire content, like this:
    > >
    > > System.out.println("data: <"+contentsOf(c)+">");
    > >
    > > data: <{Hello, World!}>
    > >
    > >
    > > Afterwards, I thought it would be better to write a method that would
    > > be
    > > able to do the same with hashtables, vectors... hell, ANY object. So
    > > far, I've implemented arrays, hashtables and lists (because that's what
    > > I encounter all the time). I just hope I'm not reinventing the wheel...
    > >

    > Sorry, you *are* reinventing the wheel.


    I was afraid so. Or maybe it's a BETTER wheel? ;-)


    > AbstractCollection (the super-class of Vector and others), AbstractMap
    > (the super-class of HashMap and others) and Hashtable have already very
    > smart toString() methods doing what you want. These toString() methods
    > are automatically called by System.out.println(...).
    > For example:
    > List list = new Vector();
    > list.add("Hello"); list.add("world!");
    > System.out.println("list: " + list);
    > results in:
    > list: {Hello, world!}
    >
    > Map map = new HashMap();
    > map.put("a","Hello"); map.put("b","world!");
    > System.out.println("map: " + map);
    > results in:
    > map: {a=Hello, b=world!}



    Yes, indeed. However, during my tests I quickly found limitations. The
    following segment of code:

    ----8<--------8<--------8<--------8<--------8<--------8<--------8<----
    Object[] o1={"hola", "que", "tal"};
    Object[] o4={new Integer(1), new Integer(2), new Integer(4)};
    Object[] o5={"hola", null, "mundo", o4};
    String[] s3={"a", null, "i ", "o", "u"};

    String a="test";
    Integer b=new Integer(123);
    String[] c={"Hello", null, "world!"};
    Hashtable d=new Hashtable();
    d.put("0", "oo");
    Hashtable e=new Hashtable();
    e.put("comp.lang", "java.programmer");
    e.put("MIGUEL", "FARAH");
    e.put("P", s3);
    e.put("Q", o5);
    e.put("H", d);
    Vector f=new Vector();
    f.add("ASDF");
    f.add(new Double(Math.PI));
    f.add(e);
    f.add(d);
    f.add(e); // yup, again
    f.add(o1);
    Vector g=new Vector();
    Hashtable h=new Hashtable();
    h.put("1", "2");
    h.put("a", "b");
    h.put(new Double(3.14159), new Integer(-1));
    h.put(new Vector(), new Hashtable());
    Object[] i={null, null, null};
    Object[] j={i, i};

    System.out.println("contentsOf(a): <"+contentsOf(a)+">\n");
    System.out.println("a.toString() : <"+a.toString() +">\n\n");
    System.out.println("contentsOf(b): <"+contentsOf(b)+">\n");
    System.out.println("b.toString() : <"+b.toString() +">\n\n");
    System.out.println("contentsOf(c): <"+contentsOf(c)+">\n");
    System.out.println("c.toString() : <"+c.toString() +">\n\n");
    System.out.println("contentsOf(d): <"+contentsOf(d)+">\n");
    System.out.println("d.toString() : <"+d.toString() +">\n\n");
    System.out.println("contentsOf(e): <"+contentsOf(e)+">\n");
    System.out.println("e.toString() : <"+e.toString() +">\n\n");
    System.out.println("contentsOf(f): <"+contentsOf(f)+">\n");
    System.out.println("f.toString() : <"+f.toString() +">\n\n");
    System.out.println("contentsOf(g): <"+contentsOf(g)+">\n");
    System.out.println("g.toString() : <"+g.toString() +">\n\n");
    System.out.println("contentsOf(h): <"+contentsOf(h)+">\n");
    System.out.println("h.toString() : <"+h.toString() +">\n\n");

    System.out.println("contentsOf(i): <"+contentsOf(i)+">\n");
    System.out.println("i.toString() : <"+i.toString() +">\n");
    System.out.println("asList(i) : <"+Arrays.asList(i)
    +">\n\n");
    System.out.println("contentsOf(j): <"+contentsOf(j)+">\n");
    System.out.println("j.toString() : <"+j.toString() +">\n");
    System.out.println("asList(j) : <"+Arrays.asList(j)
    +">\n\n");
    ----8<--------8<--------8<--------8<--------8<--------8<--------8<----

    produces the following output:

    ----8<--------8<--------8<--------8<--------8<--------8<--------8<----
    contentsOf(a): <test>

    a.toString() : <test>


    contentsOf(b): <123>

    b.toString() : <123>


    contentsOf(c): <{Hello, null, world!}>

    c.toString() : <[Ljava.lang.String;@16f0472>


    contentsOf(d): <{0=oo}>

    d.toString() : <{0=oo}>


    contentsOf(e): <{comp.lang=java.programmer, MIGUEL=FARAH, H={0=oo},
    Q={hola, null, mundo, {1, 2, 4}}, P={a, null, i , o, u}}>

    e.toString() : <{comp.lang=java.programmer, MIGUEL=FARAH, H={0=oo},
    Q=[Ljava.lang.Object;@5224ee, P=[Ljava.lang.String;@f6a746}>


    contentsOf(f): <[ASDF, 3.141592653589793, {comp.lang=java.programmer,
    MIGUEL=FARAH, H={0=oo}, Q={hola, null, mundo, {1, 2, 4}}, P={a, null, i
    , o, u}}, {0=oo}, {comp.lang=java.programmer, MIGUEL=FARAH, H={0=oo},
    Q={hola, null, mundo, {1, 2, 4}}, P={a, null, i , o, u}}, {hola, que,
    tal}]>

    f.toString() : <[ASDF, 3.141592653589793, {comp.lang=java.programmer,
    MIGUEL=FARAH, H={0=oo}, Q=[Ljava.lang.Object;@5224ee,
    P=[Ljava.lang.String;@f6a746}, {0=oo}, {comp.lang=java.programmer,
    MIGUEL=FARAH, H={0=oo}, Q=[Ljava.lang.Object;@5224ee,
    P=[Ljava.lang.String;@f6a746}, [Ljava.lang.Object;@1e63e3d]>


    contentsOf(g): <[]>

    g.toString() : <[]>


    contentsOf(h): <{3.14159=-1, a=b, 1=2, []={}}>

    h.toString() : <{3.14159=-1, a=b, 1=2, []={}}>


    contentsOf(i): <{null, null, null}>

    i.toString() : <[Ljava.lang.Object;@1004901>

    asList(i) : <[null, null, null]>


    contentsOf(j): <{{null, null, null}, {null, null, null}}>

    j.toString() : <[Ljava.lang.Object;@13e8d89>

    asList(j) : <[[Ljava.lang.Object;@1004901,
    [Ljava.lang.Object;@1004901]>


    ----8<--------8<--------8<--------8<--------8<--------8<--------8<----

    For the record, I'm still using Java 1.4.2 (we can't go to 1.5/5.0
    yet).

    Sure, the toString()/asList methods do their thing, but they don't go
    deep enough, IMHO.

    I acknowledge that my examples are quite twisted, but I want to be able
    to handle ANYTHING that comes in my way. And considering the abysmal
    quality of the code delivered by some of the consultants that worked
    for us in the recent past (and I dare not say present), I'd rather be
    prepared.
    Miguel Farah, Oct 20, 2005
    #4
  5. Miguel Farah wrote:
    [...]
    > Sure, the toString()/asList methods do their thing, but they don't go
    > deep enough, IMHO.
    >
    > I acknowledge that my examples are quite twisted,

    I agree ;-)
    > but I want to be able
    > to handle ANYTHING that comes in my way. And considering the abysmal
    > quality of the code delivered by some of the consultants that worked
    > for us in the recent past (and I dare not say present), I'd rather be
    > prepared.
    >

    I personally would not overhasty begin an endless series of curing
    symptoms without curing the underlying disease. In your case this might
    be: Make it a requirement for your blamed consultants to implement smart
    toString() methods in their classes, or better implement them yourself.
    (BTW: I assume you own their sources. Shame on you, if you don't)

    --
    "Thomas:Fritsch$ops:de".replace(':','.').replace('$','@')
    Thomas Fritsch, Oct 20, 2005
    #5
  6. Thomas Weidenfeller

    Roedy Green Guest

    On Thu, 20 Oct 2005 18:17:28 GMT, Thomas Fritsch
    <> wrote or quoted :

    >I personally would not overhasty begin an endless series of curing
    >symptoms without curing the underlying disease. In your case this might
    >be: Make it a requirement for your blamed consultants to implement smart
    >toString() methods in their classes, or better implement them yourself.
    >(BTW: I assume you own their sources.


    that is exactly what he did by posting here. Many eyes would have
    missed the cleverness already present in Collections. Yours did not.

    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
    Roedy Green, Oct 21, 2005
    #6
  7. Miguel Farah wrote:
    > I usually have to debug source code written by someone else, where
    > faulty data provokes errors. Tracing those usually implies getting
    > printouts of said data in a logfile, and then figure out the rest.
    > Usually, the quickest way is to simply stick in a System.out.println()
    > and execute... which leads to useless output like this example:


    You might consider learning to use a debugger instead of messing with
    println().

    /Thomas
    --
    The comp.lang.java.gui FAQ:
    ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
    http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/
    Thomas Weidenfeller, Oct 21, 2005
    #7
  8. Thomas Weidenfeller

    Miguel Farah Guest

    Thomas Weidenfeller wrote:
    > Miguel Farah wrote:
    > > I usually have to debug source code written by someone else, where
    > > faulty data provokes errors. Tracing those usually implies getting
    > > printouts of said data in a logfile, and then figure out the rest.
    > > Usually, the quickest way is to simply stick in a System.out.println()
    > > and execute... which leads to useless output like this example:

    >
    > You might consider learning to use a debugger instead of messing with
    > println().


    Yeah, I could... but in my experience, they're not really useful (and
    as they grow more complex, the less usefulness they have). println()s
    are simpler to handle. YMWV.
    Miguel Farah, Oct 21, 2005
    #8
  9. Thomas Weidenfeller

    Roedy Green Guest

    On 21 Oct 2005 11:33:25 -0700, "Miguel Farah" <> wrote
    or quoted :

    >Yeah, I could... but in my experience, they're not really useful (and
    >as they grow more complex, the less usefulness they have). println()s
    >are simpler to handle. YMWV.


    Try out the one in Eclipse. It is not your father's Oldsmobile.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
    Roedy Green, Oct 22, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. saurabh
    Replies:
    2
    Views:
    468
    Oystein Haare
    May 5, 2004
  2. LaptopHeaven
    Replies:
    0
    Views:
    406
    LaptopHeaven
    Oct 5, 2006
  3. Replies:
    7
    Views:
    422
  4. Lord0
    Replies:
    0
    Views:
    303
    Lord0
    Oct 2, 2008
  5. Andries

    I know, I know, I don't know

    Andries, Apr 23, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    223
    Gregory Toomey
    Apr 23, 2004
Loading...

Share This Page