admaDIC IT Solutions & Digital Media
EN     DE

Software Development : Java

Reflection - Class Inspector

by Rainer Schwarze - last update 2007-07-30

General Information

The Java Reflection API is used for retrieving information about classes during runtime. Several things are pretty simple such as retrieving all the fields which a class declares. However, as soon as generics are involved, life gets a bit more complicated. To learn more details about the Reflection API I created a little Class Inspector which is available under a BSD-style license.

This project is a playground for me. If you use this package, be aware, that a neat and stable public interface is not on my list so far. Things may change every now and then.

If you have any comments or questions about this software, you are welcome to send an email to .

^ top

Simple Example

Consider the following class:

public class A {
 Object objectA;
 Integer integerA;
 int intA;
 String [] stringAryA;

 public A() {
  super();
 }

 public Object getObjectA() {
  return objectA;
 }

 public void setObjectA(Object objectA) {
  this.objectA = objectA;
 }

 public void workForOverride() {
  /* nothing to work */
 }
}

Below is a screenshot of the inspection panel. It displays the information which is available via methods like getDeclaredFields in Class. The nodes have a different background color to indicate their context (class, field, etc.).

Screenshot with information about class A

^ top

How it Works

The class inspector application builds a tree out of the information about a class. The tree is built on demand when the user expands a node. The new nodes are created in a background thread to keep the UI responsive. After the new nodes are created, they are inserted into the tree within the Event Dispatch Thread.

The nodes are named according to the function which retrieved the information. For instance the results returned by getDeclaredFields from Class are stored in a node named declared fields. A node named parameter types represents results from the function getParameterTypes.

^ top

Information about a Class instance

Retrieving information about a Class instance is straight forward. Lets take a look at what information is available from this class:

public class SubA extends A {
 Object objectSubA;
 Integer integerSubA;
 int intSubA;

 public SubA() {
  super();
 }

 public Object getObjectSubA() {
  return objectSubA;
 }

 public void setObjectSubA(Object objectSubA) {
  this.objectSubA = objectSubA;
 }

 @Override
 public void workForOverride() {
  super.workForOverride();
 }
}

A screenshot of the inspect panel is shown below. With the reflection API we see among other things that there are three fields, three methods, one constructor and that the super class is A. Nothing fancy.

Screenshot with information about class SubA

Lets take a look at the workForOverride method (screenshot below). The list of annotations and the list of declared annotations have no elements although the sources contain the @Override annotation. Well, no surprise, because @Override is declared with @Retention(RetentionPolicy.SOURCE) and should not be there in the compiled class files. Again, nothing fancy.

Screenshot with information about class SubA

^ top

Information about a Class using Generics

Subclass of Parameterized Class

Lets take a look at these classes of which GenA_Int is a sub class of a parameterized class:

public class GenA_Int extends GenA<Integer> {
 public GenA_Int(Integer value) {
  super(value);
 }
}

public class GenA<T> {
 T value;

 public GenA(T value) {
  super();
  this.value = value;
 }

 public T getValue() {
  return value;
 }

 public void setValue(T value) {
  this.value = value;
 }
}

A screenshot of the inspect panel is shown below. The method getSuperClass returns a Class instance - its simple name is GenA. The method getGenericSuperClass returns a ParameterizedType instance which is more interesting. There is a raw type which is the super class GenA. GenA has a type parameter with the name T. The ParameterizedType also contains actual type parameters which in this case is an Integer class. So this is the connection between the type parameter T in GenA and the use of Integer as the type parameter for the super class in the declaration of GenA_Int.

Screenshot with information about class GenA_Int

Two Type Parameters

What about two type parameters? Lets look at the source and the screenshot below.

public class GenB<T,S> {
 T t;
 S s;

 public GenB(T t, S s) {
  super();
  this.t = t;
  this.s = s;
 }
}

public class Sub1GenB<T> extends GenB<T,Integer> {
 public Sub1GenB(T t, Integer s) {
  super(t, s);
 }
}

public class Sub2GenB<S> extends GenB<Integer,S> {
 public Sub2GenB(Integer t, S s) {
  super(t, s);
 }
}
Screenshot with information about class GenB and its subclasses

Nested Generics

What about "nested generics"? Here we go:

public class Sub3GenB extends GenB<Integer,GenA<String>> {
 public Sub3GenB(Integer t, GenA<String> s) {
  super(t, s);
 }
}

public class GenB<T,S> {
 T t;
 S s;

 public GenB(T t, S s) {
  super();
  this.t = t;
  this.s = s;
 }
}

public class GenA<T> {
 T value;

 public GenA(T value) {
  super();
  this.value = value;
 }
 /* some elements left out */
}
Screenshot with information about class Sub3GenB

^ top

BSD-Style License

The BSD License for the admaDIC Reflection - Class Inspector

Copyright (c) 2007 admaDIC GbR. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. All advertising materials mentioning features or use of this software must display the following acknowledgement:
    This product includes software developed by Rainer Schwarze, admaDIC.
  4. Neither the name Rainer Schwarze, admaDIC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

^ top

Download Binary and Sources

The inspector package is available as a binary and as a source archive. The binary archive contains a jar file which can be started "as usual" (double click on it or execute "java -jar reflection-0.1.0.jar").

The package is provided under a BSD-style license.

Pack / Download LinkSizeMD5 Link and Checksum

Binary

reflection-0.1.0-bin.tar.bz2 52 kB md5 file (098308f84e027473a1170845fdd54eea)
reflection-0.1.0-bin.zip 52 kB md5 file (8d6704456a444a3c5e222fdfb804ab51)

Source

reflection-0.1.0-src.tar.bz2 25 kB md5 file (f849a30cb887802e2c8c4e8867a65c44)
reflection-0.1.0-src.zip 112 kB md5 file (0fbfaf5c3d89758a39b86afce55c2913)

^ top

www.admadic.de | webmaster@admadic.de | Legal Notice and Trademarks | Privacy
© 2005-2007 - admaDIC | All Rights Reserved
All other trademarks and/or registered trademarks are the property of their respective owners
Last Change: Tue Jul 31 19:57:07 2007 GMT