Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / October 2005

Tip: Looking for answers? Try searching our database.

How to know which interfaces an object implements?

Thread view: 
Miguel Farah - 20 Oct 2005 00:05 GMT
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). To do that, I need to be able to discern
that.

This is how I've solved it (replace the first line with whatever class
you want):

Vector v=new Vector();
boolean implementsList=false;
Class[] x=v.getClass().getInterfaces();
for (int k=0;k<x.length;k++) {
   if (x[k].toString().equals("interface java.util.List"))
       implementsList=true;
}
System.out.println(implementsList);

This actually works, but is very ugly, in my opinion. Is there a more
elegant way to do the same?

Same goes for recognizing classes - I'm barely comfortable with:

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

TIA.
klynn47@comcast.net - 20 Oct 2005 00:40 GMT
Have you tried the reflection classes?
Thomas Fritsch - 20 Oct 2005 00:43 GMT
> 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
[quoted text clipped - 12 lines]
>        implementsList=true;
> }

You can replace the above 6 lines by:
  if (java.util.List.class.isAssignableFrom(v.getClass()))
or better by:
  if (v instanceof java.util.List)

> System.out.println(implementsList);
>
[quoted text clipped - 4 lines]
>
> if (v.getClass().getName().equals("java.util.Vector") { ....}
You can this shorten to:
  if (v.getClass().equals(java.util.Vector.class)) { ....}
or to:

  if (v.getClass() == java.util.Vector.class) { ....}
or by
  if (v instanceof java.util.Vector) { ....}
The last variant is not exactly equivalent to yours, but probably what you
really want, because it also accounts for  v  being an instance of a
*sub*-class of Vector.

The 'xxxx.class' thing is called 'class literal'. You may want to read about
it in the language spec.
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#251530
Explainations of the 'instanceof' operator can be found in every good Java
text-book.

Signature

"TFritsch$t-online:de".replace(':','.').replace('$','@')

Roedy Green - 20 Oct 2005 01:36 GMT
>This actually works, but is very ugly, in my opinion. Is there a more
>elegant way to do the same?

You read the javadoc. That is how mostly you discover the class
hierarchies and interface implementations.

IDEs have features to show you that info quickly.

You can also just do a cast to a interface and see if you get a
compile time or run time error.

You can also use instanceof

It depends on the context of your problem what is a reasonable way to
solve it.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.

Thomas Weidenfeller - 20 Oct 2005 11:24 GMT
> 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
Signature

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/

Miguel Farah - 20 Oct 2005 16:28 GMT
> > 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
[quoted text clipped - 5 lines]
> 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]) + ((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;
   }
Thomas Fritsch - 20 Oct 2005 17:39 GMT
> I usually have to debug source code written by someone else, where
> faulty data provokes errors. Tracing those usually implies getting
[quoted text clipped - 11 lines]
>
> 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:
[quoted text clipped - 8 lines]
> 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!}

Signature

"Thomas:Fritsch$ops:de".replace(':','.').replace('$','@')

Miguel Farah - 20 Oct 2005 18:21 GMT
> > I usually have to debug source code written by someone else, where
> > faulty data provokes errors. Tracing those usually implies getting
[quoted text clipped - 15 lines]
> 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:
[quoted text clipped - 10 lines]
> >
> 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
[quoted text clipped - 12 lines]
> 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.
Thomas Fritsch - 20 Oct 2005 19:17 GMT
[...]
> 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)

Signature

"Thomas:Fritsch$ops:de".replace(':','.').replace('$','@')

Roedy Green - 21 Oct 2005 02:44 GMT
>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.

Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.

Thomas Weidenfeller - 21 Oct 2005 08:50 GMT
> 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
Signature

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/

Miguel Farah - 21 Oct 2005 19:33 GMT
> > I usually have to debug source code written by someone else, where
> > faulty data provokes errors. Tracing those usually implies getting
[quoted text clipped - 4 lines]
> 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.
Roedy Green - 22 Oct 2005 00:52 GMT
>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.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.