SRL Archive - Reflection Tutorials

Java Reflection


Rakura

2009-08-11 06:02:30

Originally Made For Rsbot.

Prerequisites:
[INDENT]A firm understanding of the basics of Java. This includes a FIRM grasp of the concept of Object-Oriented Programming, conditionals (if statements), loops, etc. Basically, if all you know about Java is how to program for rsbot, then this isn't for you.

You have to know about Java applications (a program with a main() method) and how to use command line or an IDE to run a program << bad english.
[/INDENT]Definition:[INDENT]So a lot of noobs stroll around the forums thinking that they know everything there is to know about reflection, BCEL (I personally don't even know anything about BCEL), how the JaGex detection system works, etc. but the sad truth of the matter is, they don't. Most people, however, DO know the definition of reflection. However, this is the more official and techincal definition:[INDENT]Reflection is a technique that enables one Java class to learn details about any other class.
[/INDENT]This is VERY useful as it gives a class new ways to instance classes, to learn everything about another class, etc.

Now that we got that definition out of the way, let us dive into reflection itself.
[/INDENT]The Basics:[INDENT]EVERY Java class inherits the getClass() method which returns the class/interface of that object. It returns a Class object representing the class of that object. That may of sounded confusing but here is an example:
[/INDENT][INDENT]
Integer integer = new Integer(10);
Class integerClass = integer.getClass();
Okay, so we have a conceptual "thing" that is a Class. Now if we wanted the name of that class, simply add a .getName() to a Class object. This will return a String representing the name of the class and a reference to a package to which the class belongs to. For primitive types, the name corresponds to the type's name (such as int, float, double, boolean, etc.)

Class objects that represent arrays are handled a little differently when getName() is called on them. The name begins with one left bracket character "[" for each dimension of the array: int[][] would begin with [[ and so on. BUT that's not all, if the array is of a primitive type the next part of the name is a single character representing the type. B for byte, C for char, D for double, and so on. WARNING: boolean is Z (the only exception to the pattern). For an array of objects, the brackets are followed by an L and the name of the class. For example, if you called getName on a String[][], the result would be: [[Ljava.lang.String.

Another way to create a Class object is to use the forName class method in the class Class:

Class integer = Class.forName ("java.lang.Integer");
If you tried to use this piece of code, it will throw an exception due to the fact that forName throws a ClassNotFoundException. So you must surround any piece of code with .forName(String str) with a try-catch block. If you have no idea what I'm saying then you probably shouldn't be reading this tutorial. Throught this tutorial, I will NOT bother with doing this to save my time. ;)

For more on the class Class: http://java.sun.com/javase/6/docs/api/java/lang/Class.html (though some of this will be covered later today)
[/INDENT]Instancing In Reflection:[INDENT]
Class string = Class.forName("java.lang.String");
String str = (String)string.newInstance();
[/INDENT][INDENT]Be aware that newInstance() throws 3 exceptions which any IDE should tell you.
[/INDENT]Parts of a class in Reflection:[INDENT]Though the class Class is part of the java.lang package, most of the tools used for reflection is found in java.lang.reflect. This package includes the following packages:[INDENT]Field - for variables

Method - for methods

Constructors - for constructors

Array - for arrays

Modifier - for modifiers
[/INDENT]Each of these classes have methods that allows you to work with their respective specialties.

A method object holds information about a single method of a class. To find all methods of this, create a Class object for that class and call getDeclaredMethods() on that object. This returns an array of Method objects. WARNING: It doesnt not return the inherited methods.

Once you have a Method object, you can call these methods to find out more about the method: getParameterTypes (returns an array of Class objects representing each argument), getReturnType (returns a single class Object representing the return type of the method), getModifiers (returns an int value that represents the modifiers that apply to the method, such as public, private, etc.).

It may seem strange that getModifiers return a int value. however, you can just use the toString class method of Modifier. For example:

int mods = current.getModifiers();
System.out.println (Modifier.toString(mods));
To illustrate what we have learned so far, take a look at my little application that will inspect all the methods of any class for you. You simply enter the name of the class as an argument when using command line. If nothing is entered, this class will inspect itself. WARNING: You MUST enter the full package of the class if the class is not in the same package as MethodInspector.
[/INDENT]

import java.lang.reflect.*;

public class MethodInspector {
public static void main(String[] arguments) {
Class inspect;
try {
if (arguments.length > 0)
inspect = Class.forName(arguments[0]);
else
inspect = Class.forName("MethodInspector");
Method[] methods = inspect.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
Method methVal = methods[i];
Class returnVal = methVal.getReturnType();
int mods = methVal.getModifiers();
String modVal = Modifier.toString(mods);
Class[] paramVal = methVal.getParameterTypes();
StringBuffer params = new StringBuffer();
for (int j = 0; j < paramVal.length; j++) {
if (j > 0)
params.append(", ");
params.append(paramVal[j].getName());
}
System.out
.println(modVal + " " + returnVal.getName() + " "
+ methVal.getName() + " " + "( " + params
+ " )" + "\n");
}
} catch (ClassNotFoundException c) {
System.out.println(c.toString());
}
}

}
This guide may or may not be updated.

Happy Coding!!

R0b0t1

2009-08-11 06:41:41

I, sir, would like to "lol" you out of town.

noidea

2009-08-11 07:28:22

i liek copeh pastaz

Method

2009-08-11 08:22:48

The type signature of boolean is the only exception…oh wait long's type signature is "J". That doesn't match up either!

Also, reference types are "L" plus fully qualified class name ("java/lang/String") plus semicolon ";" –> "Ljava/lang/String;". You seem to have missed out on the last part.

Rakura

2009-08-11 17:13:32

From: Method
The type signature of boolean is the only exception…oh wait long's type signature is "J". That doesn't match up either!

Also, reference types are "L" plus fully qualified class name ("java/lang/String") plus semicolon ";" –> "Ljava/lang/String;". You seem to have missed out on the last part.


Oops thanks a lot. I'll edit later. :p