giulio
giulio

Reputation: 659

Understanding an Object Reflection advantage in Java

I am learning about Object Reflection in Java and read the following advantage it offers (From Cracking the Coding Interview, Laakmann McDowell):

We can call methods by name, when we don't know the method in advance. For example, we may let the user pass in a class name, parameters for the constructor, and a method name. We can then use this information to create an object and call a method. Doing these operations without reflection would require a complex series of if-statements, if it's possible at all

I have trouble understanding this point: If we know the method name, can't we just call it anyway?

Upvotes: 1

Views: 305

Answers (4)

flo
flo

Reputation: 10241

You can call the method directly by

instance.method();

only if you also know the class in advance aka during compile-time. Then you also could use an import-statement and use the class definition and the class' constructor directly (if they have the correct scope like public).

The description above applies to classes, we don't know during develop/compile-time and therefore we cannot create directly via construtor or even cast to. We can call a method of an unknown class with the informations given above as follows:

ClassLoader cls = ...;
Class<?> clazz = cls.loadClass("someClass");
Object newInstance = clazz.newInstance(); // or invoke constructor found by clazz.getConstructor()...
Method m = clazz.getMethod("methodName", methodParmeterClasses); // array of method parameter classes
m.invoke(newInstance, methodParameters ); //array of parameterse

Upvotes: 1

Cuzz
Cuzz

Reputation: 448

Fast example, get list of method names and finding setters:

public Map<String, String> getSettersList( Class<T> domainClass, List<Field> fields )
{
    Method[] methods = domainClass.getMethods();
    Map<String, String> setterMap = new HashMap<String, String>();
    for ( int j = 0; j < fields.size(); j++ )
        for ( int i = 0; i < methods.length; i++ )
        {
            if ( methods[i].getName().toLowerCase().equals( "set" + fields.get( j ).getName().toLowerCase() ) )
            {
                if ( methods[i].getParameterTypes().length == 1 )
                    setterMap.put( fields.get( j ).getName(), methods[i].getName() );

            }
        }
    return setterMap;

}

Then invoke methods with some value:

   T instance = createInstance( domainClass );
   Method setterMethod = instance.getClass().getMethod( setterList.get( field.getName() ), field.getType() );
   Object value = rs.getObject( column );
   if ( value != null )
   {
     value = castTypes( field.getType(), rs.getObject( column ) );
   }
   // invoke setter of "field" with value
   setterMethod.invoke( instance, value );

Upvotes: 1

ferjani
ferjani

Reputation: 99

Another "good" point is the following: the method may be protected (like URLClassLoader.addURL), using reflection you may call it as specified here

Upvotes: 1

NESPowerGlove
NESPowerGlove

Reputation: 5496

It means that the reflection API allows you to call a method by it's name at runtime. This would be useful if you don't know the name of the method you want to call when you compile.

For example, say you made some sort of small scripting language that you want to quickly call various methods that exist in your Java code in which you load these scripting files in at run time. You could grab the bytes that make up the name in the scripting file and call the method.

Upvotes: 2

Related Questions