Advanced Programming
SUT • Spring 2019
What is RTTI?
Why we need it?
Type information
Java and Reflection
Suppose you want to implement RPC or RMI
What do you need?
Socket Programming
Serialization
How do you invoke methods in other side?
Suppose you should write a program
It reads the name of a class
And the name of one of its methods
And all of its parameters
The program
creates and object from the specified class
and invokes the specified method
with specified parameters
How can you implement it?
What is its application?
RPC and RMI
Object transfer to a web service
Runtime type information (RTTI)
Allows you to discover and use type information while a program is running
This feature is also called Reflection in java
With RTTI, you can ask an object reference the exact type that it’s referring to.
And you can get information about it its characteristics and capabilities
Methods, constructors, fields, …
And you can call its methods and get its properties
How can you implement the requested program with RTTI?
How can you simulate RPC and RMI?
How can you send an object via web-service?
How type information is represented at run time?
This is accomplished through a special kind of object
It is called the Class object
it contains information about the class
Java performs its RTTI using the Class object
There’s one Class object for each class that is part of your program
Each time you write and compile a new class, a single Class object is also created
and stored, appropriately enough, in an identically named .class file
To make an object of that class, JVM uses a subsystem called a class loader
A classes is loaded into the JVM dynamically
upon the first use of the class
When?
when the program makes the first reference to a static member of that class
The constructor is also a static method of a class!
Even though the static keyword is not declared
Instantiation: using the new operator = reference to a static member (constructor)
A Java program isn’t completely loaded before it begins
Pieces of it are loaded when necessary
This is called Dynamic loading
Different from many traditional languages
Enables difficult or impossible behavior
to duplicate in a statically loaded language like C++.
The class loader first checks:
Is the Class object for that type loaded?
If not, class loader finds the .class file and loads it
A customized class loader may load the class from a DB
Method method = String.class.getMethod("substring", int.class);
Object value = method.invoke("Taghi Taghavi", 6);
System.out.println((String)value);
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
Class clazz = object.getClass();
Annotation[] annotations = clazz.getAnnotations();
Field[] fields = clazz.getFields();
Constructor[] constructors = clazz.getConstructors();
package drawing;
class MyClass{
String name;
public MyClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Class c = Class.forName("drawing.MyClass");
Constructor constructor = c.getConstructor(String.class);
MyClass instance = (MyClass) constructor.newInstance("Ali Alavi");
Field field = instance.getClass().getDeclaredField("name");
field.set(instance, "Taghi Taghavi");
System.out.println(instance.getName());
Tells you if an object is an instance of a particular type
Use instanceof before a downcast
when you don’t have other information that tells you the type of the object;
Otherwise, you may end up with a …?
ClassCastException
if(x instanceof Dog)
((Dog)x).bark();
instanceof returns false if the reference is null
void f(Object c){
if(c instanceof Serializable && c instanceof String)
System.out.println("YES!");
}
There’s an important difference between instanceof and the direct comparison of the Class objects
But instanceof and islnstance() produce equivalent results
if(c instanceof String)
...
if(c.getClass().equals(String.class))
...
Compile time code (Hard coded)
1. ClassName.class
Class clazz = Person.class;
Runtime
2. Class.forName
Class clazz = Class.forName("edu.sharif.ce.Rectangle");
3. reference.getClass
Object o = new Person();
Class clazz= o.getClass();
Example1
Class<Person> clazz = Person.class;
Person p = clazz.newInstance();
No cast is needed
Example2
Object o = new Person();
Class<? extends Object> c = o.getClass();
What is wrong with this code?
class GenericType<T>{
private T element;
public void f(){
Class c2 = element.getClass();
Class c1 = T.class;
}
}
class MyClass{
private void privateMethod(){
}
}
...
MyClass instance = new MyClass();
Method method = instance.getClass().
getDeclaredMethod("privateMethod");
method.setAccessible(true);
method.invoke(instance);
public static void swap(Integer i, Integer j) {
try {
Integer lastJ = new Integer(j);
Field value = Integer.class.getDeclaredField("value");
value.setAccessible(true);
value.set(j, i);
value.set(i, lastJ);
value.setAccessible(false);
} catch (Exception e) {
e.printStackTrace();
}
}