Runtime type information (RTTI) refers to the correct identification of the type of your objects at run time. When you write code, it is generally desirable to do so in a way that takes advantage of OOP features like encapsulation and inheritance to make your program easily extensible, by for instance, as much as possible manipulating references to base classes and letting polymorphism work for you. Essentially, when you create a new object with a base class reference, the process necessarily involves an upcast to the base class from a more specialised type. There are many advantages to this style of programming not least of which includes the ability to simulate a more dynamic behaviour. Upcasting is a fairly straightforward process that the Java interpreter undertakes automatically, because there is very little risk associated with it. RTTI describes the reverse of this process when you wish to focus on a specific type for example to perform a particular operation. For instance, consider the following Game class hierarchy:- package; abstract class Game { public int players; public String toString() { return "Game"; } void play() { System.out.println("playing " + this + "()"); } } class Charade extends Game { public String toString() { return "CharadeGame"; } } class Chess extends Game { public String toString() { return "Chess"; } } class CardGame extends Game { public String toString() { return "CardGame"; } } class BlackJack extends CardGame { public void shuffle() { System.out.println("Shuffle cards"); } public String toString() { return "BlackJack"; } } class OnlineGame extends Game { public String toString() { return "OnlineGame"; } } This is a fairly accurate representation of the structure of libraries that exist within an OO paradigm, even though in reality some classes inherit from base classes in other packages. In the following code a List is configured to hold subtypes of the abstract Game class. Each type ofGame is upcast to the List container which treats all elements as Game references having no memory of individual types. We can identify the benefit of RTTI in the playGame() method where we iterate through the list and the correct type is identified in the call toplay() because polymorphism allows us to make the correct binding at runtime:- package; import java.util.Arrays; import java.util.List; public class Arcade { static void playGame(List<Game> options) { for(Game selection : options); } public static void main(String[] args) { List<Game> games = Arrays.asList(new Chess(), new CardGame(), new BlackJack()); playGame(games); } } /* Output playing Chess() playing CardGame() playing BlackJack() *// The above example is the most basic form of RTTI and why polymorphism is understood to be a general goal in object oriented programming. There are other circumstances when you might need to identify a specific type, perhaps to enable some operation unique to a specific type, circumstances for which you can not rely on polymorphism by itself. Java allows you to discover runtime type information in one of two ways. The first approach assumes all type information is available at compile time which you can obtain by querying the object reference. For instance, suppose we wanted to ensure the cards are shuffled before playing a game ofBlackJack. We could use RTTI to identify this specific type in order to call the appropriate method:- package; import java.util.Arrays; import java.util.List; public class GettingType { public static void playGame(List<Game> options) { for(Game selection : options) { Class<? extends Game> type = selection.getClass(); if(type.isAssignableFrom(BlackJack.class)) ((BlackJack)selection).shuffle();; } } public static void main(String[] args) { List<Game> games = Arrays.asList(new Chess(), new BlackJack(), new Charade()); playGame(games); } } /* Output playing Chess() Shuffle cards playing BlackJack() playing Charade() *// In this instance, we query the object reference for type information using thegetClass() method, and then apply theisAssignableFrom() method to the resulting reference determine if this class is the same or a superclass of theBlackJack class. If it is, we cast the object to aBlackJack object and then call shuffle(). The logic of type as you will no doubt come to understand is sound and quite uncomplicated. You can also use theinstanceof keyword to check for the type of an object, for example prior to making a cast:- package; public class TypeTest { public static void main(String[] args) { Game aGame = new BlackJack(); if(!(aGame instanceof BlackJack)) System.out.println("Not an instance"); ((BlackJack)aGame).play(); } } /* Output playing BlackJack() *// The other approach to discovering type information is to make use of a reflection mechanism by which means you can discover and use previously unavailable class information, exclusively at runtime. In any event, either approach requires a sound knowledge of how Java represents type information at runtime. 

The Class object

Java uses instances of the class Class to represent type information at runtime. Type refers to the classes and interfaces in a running Java application which are automatically loaded by the Java Virtual Machine (JVM) using a specialClassLoader mechanism. In effect, there exists aClass object for every class that is a part of your program which consists of information about your class and is used for creating all the other objects of your class. You can get a reference to this Class object by calling thegetClass() method as we did in a previous example. However in circumstances where this option might not be available, you can create a Class reference directly which can then be manipulated just like you do any other reference to conveniently discover all sorts of type information. You can return a Class reference by either calling thestatic forName() method or by using the class literal. Here is an example using both techniques;-public class GettingTypeInfo { static void printTypeInfo(Class<? extends Game> whichClass) { System.out.println("Class name - " + whichClass.getName()); System.out.println("Simple name - " + whichClass.getSimpleName()); System.out.println("isInterface - " + whichClass.isInterface()); System.out.println("Package - " + whichClass.getPackage()); System.out.println("SuperClass " + whichClass.getSuperclass()); } public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class<? extends Game> aClass = Class.forName(""); //class literal syntax Class anotherClass = Chess.class; printTypeInfo(aClass); System.out.println("isInstance - " + aClass.isInstance(new BlackJack())); System.out.println("------------------------------- "); printTypeInfo(anotherClass); System.out.println("isInstance - " + anotherClass.isInstance(new Game())); System.out.println("------------------------------- "); Object anObj = aClass.newInstance(); System.out.println("NewInstance " + anObj.toString()); } } /* Output Class name - Simple name - BlackJack isInterface - false Package - package SuperClass class isInstance - true ------------------------------- Class name - Simple name - Chess isInterface - false Package - package SuperClass class isInstance - false ------------------------------- NewInstance BlackJack *//The first statement in the main() makes use of thestatic forName() method to obtain a valid reference to the BlackJack Class, by contrast, the second statement makes use of a class literal to achieve the same effect. Both techniques are equally valid, but have subtle implications related to the way the class object is initialised. Notice the use of generic syntax with Class types in particular in the call to the forName() method. Generics provide a way to constrain objects to subtypes of a particular type. Here the wildcard symbol   symbol is used in combination with the extendskeyword to constrain all references to subtypes ofGame. Class references also work fine without the use of generics, however it is advisable to use generic syntax as you are likely to find out about mistakes much sooner TheprintTypeInfo() method displays output from a number of methods available to objects of the class Classproviding access to useful type information. TheisInstance() and newInstance() methods are also used in the main() to test for compatibility and create a new instance respectively. As you become used to working with types, you will find them useful in circumstances where you might wish to be able to identify individual types perhaps for some specific purpose. For instance, suppose you wanted a way to keep a track of the number of individual Gametypes generated by your application. The first thing you might need is a way to link the initialisation of each Gameobject with it's corresponding Class object. One way to do this might be to use a variation of the templatedesign pattern to create an abstract method that returns a list of types with which you might generate new instances of Game types:- package; import java.util.List; import java.util.Random; public abstract class InitGame { static private Random generator = new Random(); public abstract List<Class<? extends Game>> getTypes(); public Game aRandomGame() { int index = generator.nextInt(getTypes().size()); try { return getTypes().get(index).newInstance(); } catch(InstantiationException ref) { throw new RuntimeException(ref); } catch(IllegalAccessException ref) { throw new RuntimeException(ref); } } public Game[] createGames(int capacity) { Game[] arrayOfGames = new Game[capacity]; for(int i = 0; i < capacity; i++) arrayOfGames[i] = aRandomGame(); return arrayOfGames; } } Essentially, this class uses a random number generator to index into a list of types in order to instantiate a new Game object. A second method uses this pseudo-random algorithm to return an array of games. As with all abstract classes, an inheriting class will need to implement the abstract getTypes() method. The following class uses class literals to create a list ofClass references:- package; import java.util.Arrays; import java.util.List; public class GameTypeCreator extends InitGame { @SuppressWarnings("unchecked") public static final List<Class<? extends Game>> gameTypes = Arrays.asList(Chess.class, CardGame.class, BlackJack.class, Charade.class, OnlineGame.class); public List<Class<? extends Game>> getTypes() { return gameTypes; } } The final class in this sequence uses aMap to track the number individual type ofGame objects created. Here's how:- package; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; class Util { static public Map<Class<? extends Game>, Integer> mapData(List<Class<? extends Game>> key, int value) { Map<Class<? extends Game>, Integer> data = new HashMap<>(); Iterator<Class<? extends Game>> sequence = key.iterator(); while(sequence.hasNext()) data.put(, value); return data; } } public class CountGame extends LinkedHashMap<Class<? extends Game>, Integer> { public CountGame() { super(Util.mapData(GameTypeCreator.gameTypes, 0)); } public void count(Game aGame) { for(Map.Entry<Class<? extends Game>, Integer> anEntry : entrySet()) //Class.isInstance to dynamically test for types if(anEntry.getKey().isInstance(aGame)) put(anEntry.getKey(), anEntry.getValue() + 1); } public String toString() { StringBuilder aString = new StringBuilder("{"); for(Map.Entry<Class<? extends Game>, Integer> anEntry : entrySet()) { aString.append(anEntry.getKey().getSimpleName()); aString.append("="); aString.append(anEntry.getValue()); aString.append(", "); } aString.delete(aString.length()-2, aString.length()); aString.append("} "); return aString.toString(); } } public static void main(String[] args) { CountGame aGameCounter = new CountGame(); GameTypeCreator aGameTypeCreator = new GameTypeCreator(); for(Game aGame : aGameTypeCreator.createGames(15)) { System.out.print(aGame.getClass().getSimpleName() + " "); aGameCounter.count(aGame); } System.out.println(); System.out.println(aGameCounter); } } /* Output OnlineGame BlackJack Charade BlackJack BlackJack Chess CardGame Chess OnlineGame BlackJack BlackJack Chess BlackJack Charade Charade {Chess=3, Charade=3, BlackJack=6, OnlineGame=2, CardGame=7} *// In this example, a Map is preloaded using amapData() utility that accepts a list ofClass types restricted to subtypes of theGame class and an integer value, zero in this particular instance. In the count(), theisInstance() method is used to test for type and then increment the value entry by one. A Map can not contain duplicate keys and each key can only map to one value so it is the perfect tool for this kind of application. ThetoString() method is overridden to provide a formatted view of the Map. Adding a new type ofGame is a simply a matter of making an update to the static gameTypes list in theGameTypeCreator class. This is a useful tool limited only by the fact that it can only be used to count types ofGame because the Map has been preloaded with Game types. A more useful tool would be one that we could use to count any type:- package; import java.util.HashMap; import java.util.Map; public class CountAnyType extends HashMap<Class<?>, Integer> { private Class<?> baseType; public CountAnyType(Class<?> aType) { this.baseType = aType; } public void checkType(Object arg) { Class<?> aType = arg.getClass(); if(!baseType.isAssignableFrom(aType)) throw new RuntimeException("Wrong type! " + arg); count(aType); } public void count(Class<?> aType) { Integer sum = get(aType); put(aType, sum == null ? 1 : sum + 1); Class<?> superClass = aType.getSuperclass(); if(superClass != null && baseType.isAssignableFrom(superClass)) count(superClass); } public String toString() { StringBuilder aString = new StringBuilder("{"); for(Map.Entry<Class<?>, Integer> anEntry : entrySet()) { aString.append(anEntry.getKey().getSimpleName()); aString.append("="); aString.append(anEntry.getValue()); aString.append(", "); } aString.delete(aString.length()-2, aString.length()); aString.append("} "); return aString.toString(); } public static void main(String[] args) { CountAnyType aTypeCounter = new CountAnyType(Game.class); GameTypeCreator aGameCreator = new GameTypeCreator(); for(Game aGame : aGameCreator.createGames(15)) { System.out.print(aGame.getClass().getSimpleName() + " "); aTypeCounter.checkType(aGame); } System.out.println(); System.out.println(aTypeCounter); } } /* Output Charade Charade Chess BlackJack BlackJack BlackJack CardGame BlackJack Charade CardGame OnlineGame Charade Charade Chess CardGame {Game=15, Charade=5, BlackJack=4, OnlineGame=1, Chess=2, CardGame=7} *// In this example, we use a wildcard<?> argument to specify the type of the class, effectively making it possible to use any type with our container. We have also introduced a checkType() method that allows us to verify that we are counting the correct type using theisAssignableFrom() method. The count()method in this example, first counts the specific type and then recursively counts the base type. You would be correct to imagine that it would be possible to make a more sophisticated design in our approach to generating Game objects in circumstances where we were unconcerned about keeping track of types or for that matter if we had to generate Gameobjects with a much greater frequency. Here is an approach that makes use of the Factory design pattern by registering factories for the types to be created directly in the base class:-package; import java.util.ArrayList; import java.util.List; import java.util.Random; interface GameFactory<T> { T createGame(); } class Game { static List<GameFactory<? extends Game>> factory = new ArrayList<>(); private static Random generator = new Random(); public String toString() { return getClass().getSimpleName(); } static { factory.add(new Charade.Factory()); factory.add(new Chess.Factory()); factory.add(new Scrabble.Factory()); factory.add(new Monopoly.Factory()); factory.add(new BlackJack.Factory()); factory.add(new OnlineGame.Factory()); factory.add(new VideoGame.Factory()); } public static Game autoCreate() { int index = generator.nextInt(factory.size()); return factory.get(index).createGame(); } } class PartyGame extends Game {} class Charade extends PartyGame { public static class Factory implements GameFactory<Charade> { public Charade createGame() { return new Charade(); } } } class BoardGame extends Game {} class Chess extends BoardGame { public static class Factory implements GameFactory<Chess> { public Chess createGame() { return new Chess(); } } } class Scrabble extends BoardGame { public static class Factory implements GameFactory<Scrabble> { public Scrabble createGame() { return new Scrabble(); } } } class Monopoly extends BoardGame { public static class Factory implements GameFactory<Monopoly> { public Monopoly createGame() { return new Monopoly(); } } } class CardGame extends Game {} class BlackJack extends CardGame { public static class Factory implements GameFactory<BlackJack> { public BlackJack createGame() { return new BlackJack(); } } } class OnlineGame extends Game { public static class Factory implements GameFactory<OnlineGame> { public OnlineGame createGame() { return new OnlineGame(); } } } class VideoGame extends Game { public static class Factory implements GameFactory<VideoGame> { public VideoGame createGame() { return new VideoGame(); } } } public class GameFactories { public static void main(String[] args) { for(int i = 0; i < 10; i++) System.out.println(Game.autoCreate()); } } /* Output Charade OnlineGame Charade BlackJack OnlineGame Scrabble Scrabble Chess OnlineGame Chess *// The GameFactory interface uses generic syntax and consequently is able to return a different type based on it's implementation. In this way, adding a new type of Game does not require too much effort, except to register it's inner GameFactory class in thefactory list in the base class . The genius of this design is in its simplicity and this is exactly what design patterns are able to do. They provide you with the ability to encapsulate change. 

The Reflection Mechanism

The RTTI mechanisms discussed thus far have in common the advantage of being able to discover type information for objects whose types will have been available at compile time, in other words these classes must have been compiled as a part of your program. Java uses reflection to discover and use classes at runtime about which you had no prior information. This capability is useful in circumstances where your application might need to make use of a foreign utility which might be accessed over a network connection, on the internet or in some other similar fashion to create and execute objects on remote platforms in a technique known as Remote Method Invocation (RMI). Java's reflection implementation consists of a number of classes within the java.lang.reflect library that can be used to represent the fields, methods and constructors after which they have been appropriately named. TheConstructor class for instance provides access to a single class constructor, the Field class includesgetter() and setter() methods to read and modify Field objects and the Method class includes an invoke() method by which means you might invoke the underlying method associated with theMethod object. These classes implement theMember interface which reflects identifying information about a single member. The class Classsupports reflection by including a number of convenience methods by which means you might discover and use type information at runtime. Reflection is also a useful tool for dynamically extracting information about a class, for example to reveal the entire interface including inherited and overridden methods. Here is a nifty little tool that uses reflection to automatically reveal information about a class at runtime. You can run this tool on any class to save you time from having to trawl through endless lines of documentation:- package; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.regex.Pattern; public class InterfaceLookup { private static Pattern packageNames = Pattern.compile("\\w+\\."); public static void showInterface(Object ref) { try { Class<?> whichClass = Class.forName(ref.getClass().getName()); Constructor[] constructors = whichClass.getConstructors(); Method[] methods = whichClass.getMethods(); for(Constructor aConstructor : constructors) System.out.println(packageNames.matcher(aConstructor.toString()) .replaceAll("")); for(Method aMethod : methods) System.out.println(packageNames.matcher(aMethod.toString()) .replaceAll("")); } catch(ClassNotFoundException exceptionRef) { System.out.println("Class does not exist!"); } } public static void main(String[] args) { showInterface(new InterfaceLookup()); } } /* Output public InterfaceLookup() public static void main(String[]) public static void showInterface(Object) public final native void wait(long) throws InterruptedException public final void wait(long,int) throws InterruptedException public final void wait() throws InterruptedException public boolean equals(Object) public String toString() public native int hashCode() public final native Class getClass() public final native void notify() public final native void notifyAll() *// The example uses theforName() to return a reference to the current class and then uses convenience methods to return an array of constructors and methods which it can then iterate through and print out individually. The output is the result of using a regular expression to replace class name qualifiers. This is a quick and easy way to find out all you need to know about a class's interface while coding. As part of it's reflection mechanism, Java also provides classes and interfaces by which means you might implement dynamic proxies which are modeled on the Proxy design pattern. Proxy is a pattern that allows you to provide a surrogate or placeholder for another object in order to control access to it. This is useful in circumstances where you wish to differ the full cost of an objects creation until you actually need it or if you wanted to provide for additional operations you do not wish to be a part of your main object. For instance, consider a drawing application that renders graphics on screen in a scenario where drawing an image is a costly operation you only want to undertake when necessary. You can implement an image proxy between the Image and the calling client so that you can control when and how you create an Image. The following code provides a better illustration:- package; interface Graphic { void draw(); } class Image implements Graphic { public void draw() { System.out.println("Hello!"); } } class ImageProxy implements Graphic { private Graphic anImage; public ImageProxy(Graphic args) { this.anImage = args; } public void draw() { System.out.println("\"Calling Image..\""); anImage.draw(); } } public class DrawingApplication { public static void drawImage(Graphic aGraphic){ aGraphic.draw(); } public static void main(String[] args) { drawImage(new ImageProxy(new Image())); } } /* Output "Calling Image.." Hello! *// The benefits of such a design may not be immediately obvious, however, it does provide us with additional options for instance, we can easily add code to the image proxy to keep track of calls to the Image or to measure the overhead of such calls. Java provides classes to implement a proxy instance that will handle method calls dynamically through the use of an InvocationHandlerinterface. We can re-implement our image proxy to act as an invocation handler like so:- package; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; class AnotherImageProxy implements InvocationHandler { private Graphic anImage; public AnotherImageProxy(Graphic args) { this.anImage = args; } public Object invoke(Object proxy, Method aMethod, Object[] args) throws Throwable { System.out.println("\"Calling Image..\""); return aMethod.invoke(anImage, args); } } public class AnotherDrawingApplication { public static void drawImage(Graphic whichImage){ whichImage.draw(); } public static void main(String[] args) { Graphic proxy = (Graphic)Proxy.newProxyInstance(Graphic.class.getClassLoader(), new Class[]{Graphic.class}, new AnotherImageProxy (new Image())); drawImage(proxy); } } /* Output "Calling Image.." Hello! *//In this example, we implement the <>code>invoke() method which is responsible for processing a method invocation on a proxy instance and returning the result, which in this case happens to be a Method object used to invoke the underlying method which it represents. In the main() a proxy instance is returned using the staticnewProxyInstance() method which accepts a class loader, an array of interfaces to be implemented and the implemented invocation handler, which is handed theImage object as a part of its constructor. In this case it's probably easiest to pass an existingClassLoader like the Graphic.classreference. RTTI opens up a whole new world of programming possibilities as you come to understand how types provide you with backdoor access into pretty much any interface regardless of access permissions. For instance, consider the following simple interface in the package:- package; public interface AnInterface { void interfaceMethod(); }Suppose you wanted to hide the implementation of this interface to deter your customers from relying on it so that you might be free to change it at a later stage? You might think it is enough to restrict the implementation to package access thereby making it inaccessible to clients outside of the package like so:-package; class HiddenImplementation implements AnInterface { private String aField = "Can't touch this"; public void interfaceMethod(){ System.out.println("public HiddenImplementation.interfaceMethod()"); } public void aMethod(){ System.out.println("public HiddenImplementation.aMethod()"); } void bMethod() { System.out.println("package HiddenImplementation.bMethod()"); } private void cMethod() { System.out.println("private HiddenImplementation.cMethod()"); } protected void dMethod() { System.out.println("protected HiddenImplementation.dMethod()"); } public String toString(){ return aField; } } public class PublicInterface { public static AnInterface makeAnInterface() { return new HiddenImplementation(); } } The PublicInterface class produces an implementation of AnInterface and is the only visible part of this package and you would expect your implementation to be fairly safe? Not exactly, I'm afraid. With reflection, anyone who knows the name of your class members can easily get around this restriction like so:- import java.lang.reflect.Field; import java.lang.reflect.Method; import; import*; public class HackImplementation { static void hackInterface(Object anObject, String member) throws Exception { if(member.equals("aField")) { Field whichField = anObject.getClass().getDeclaredField(member); System.out.println(anObject.toString()); whichField.setAccessible(true); whichField.set(anObject, "Yes I can"); System.out.println(anObject.toString()); } else { Method whichMethod = anObject.getClass().getDeclaredMethod(member); whichMethod.setAccessible(true); whichMethod.invoke(anObject); } } public static void main(String[] args) throws Exception { AnInterface newInterface = PublicInterface.makeAnInterface(); newInterface.interfaceMethod(); //Compile error aField can not be resolved //!newInterface.aField; //Compile error method undefined for type AnInterface /* newInterface.aMethod(); newInterface.bMethod(); newInterface.cMethod(); newInterface.dMethod(); */ hackInterface(newInterface, "aField"); hackInterface(newInterface, "aMethod"); hackInterface(newInterface, "bMethod"); hackInterface(newInterface, "cMethod"); hackInterface(newInterface, "dMethod"); } } /* Output public HiddenImplementation.interfaceMethod() Can't touch this Yes I can public HiddenImplementation.aMethod() package HiddenImplementation.bMethod() private HiddenImplementation.cMethod() protected HiddenImplementation.dMethod() *// The example demonstrates how reflection allows you to get around all sorts of restrictions to access and change any field even those markedprivate and call just about any method no matter the level of the access specifier. With thesetAccessible() method you can modify fields and invoke methods, including even those within inner and anonymous classes, are still accessible with reflection. Even if you try to avoid this by distributing only compiled code so that your members are inaccessible, that is still not entirely the case as Java's class file disassembler (javap) can still be used to reveal all your class members. For instance the -private flag can be used to indicate that all members should be displayed includingprivate ones. Running the following command will reveal everything you wish to know about our hidden class.
javap -private HiddenImplementation
In reality, hardly anything is hidden from reflection and most are susceptible to change, with the exception only of fields markedfinal. On the flip side if you choose to misuse reflection in your program, committing all sorts of access violations, then you really will only have yourself to blame if a subsequent update to your library succeeds in breaking your code, which I am certain will be a very unpleasant experience Reflection gives you the keys to a new whole new world of dynamic programming in which having access to runtime type information allows for a very different style of programming with which it is easy to get carried away. It is important to remember to use RTTI and reflection in a way that is not detrimental to polymorphism as the most effective way to provide for extensibility in your programs.