如何使用Java反射与泛型参数



我需要使用泛型参数的反射。下面是我尝试做的一个示例类和测试类。运行测试,我得到错误:

[ERROR: Method not found exception]: Method name 'EST2GMT'

这是我的反射类与通用;

/*
 * File: MyTransformer.java
 * Created: Jul 22, 2014
*/
package company.online.project.my.transform;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import org.apache.log4j.Logger;
public class MyTransformer< T >
{
Logger LOG = Logger.getLogger( MyTransformer.class );
public T tranform( String functionName, T arg )
{
    try
    {
        Method method = this.getClass().getDeclaredMethod( functionName, arg.getClass() );
        return (T) method.invoke( this, arg );
    }
    catch ( NoSuchMethodException e )
    {
        System.out.println( "[ERROR : Method not found exception] : Method name '" + functionName + "'" );
    }
    catch ( java.lang.IllegalAccessException e )
    {
        System.out.println( "[ERROR : Illegal Access exception] : " + e.getMessage() );
    }
    catch ( java.lang.reflect.InvocationTargetException e )
    {
        System.out.println( "[ERROR : Invocation Target not found exception] : " + e.getMessage() );
    }
    return null;
}
public Date convert2Date( String date )
{
    LOG.debug( "convert2Date function called" );
    return new Date();
}
public Calendar EST2GMT( Calendar estTime )
{
    LOG.debug( "EST2GMT function called :" + estTime.getTime().toString() );
    return new GregorianCalendar( 2013, 0, 31 );
}
public String createcompanyKeys( List<T> values )
{
    LOG.debug( "EST2GMT function called" );
    return "String";
}
}
下面是我的测试类:
package company.online.project.my.transform;
import java.lang.reflect.InvocationTargetException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MyTransformerTest
{
MyTransformer transformer;
@Before
public void setUp()
{
    transformer = new MyTransformer();
}
@Test
public void testGetMethod() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
        IllegalAccessException, InvocationTargetException
{
    Calendar calendar = new GregorianCalendar( 2013, 0, 31 );
    Assert.assertEquals( Calendar.class, transformer.tranform( "EST2GMT", calendar.getClass() );
}
}

您正在将GregorianCalendar传递给接受Calendar的方法。但是通过反射,您没有发现任何方法需要GregorianCalendar,即使在正常的Java方法调用中将参数类型的子类的实例传递给方法是合法的。

要找到接受Calendar的方法,然后如果您没有找到与Class完全匹配的方法,则捕获NoSuchMethodException并再次尝试使用类的超类,您可以使用getSuperclass()方法从Class对象中获得该类,直到您甚至使用Object也未能找到该方法。

同时,您正在将Class对象作为实际参数传递给使用反射调用的方法。

transformer.tranform( "EST2GMT", calendar.getClass())

传递实际的对象。另外,在 () s之后调用.getClass() ,以获得返回对象的类。

transformer.tranform( "EST2GMT", calendar).getClass()

测试用例仍然会失败,因为返回的实际类型是GregorianCalendar,而不是同一个类Calendar。这将通过:

Assert.assertEquals( GregorianCalendar.class,
    transformer.tranform( "EST2GMT", calendar ).getClass() );

如果你只是想知道它是否是任何类型的Calendar,一个instanceof就足够了:

Assert.assertTrue(transformer.tranform("EST2GMT", calendar) instanceof Calendar);

相关内容

  • 没有找到相关文章

最新更新