检测对象是否覆盖了toString()

时间:2014-04-04 15:28:38

标签: java reflection override

我收到一个对象,需要记录它。其中一些有cusom toString(),然后我想使用它,但有些没有,我得到像mightypork.rogue.bus.events.MouseMotionEvent@2d19587d之类的东西。

我正在寻找一种动态的方法(可能带有反射?)检查传入的对象是否有toString()覆盖了自己。

String objToString(Object o)
{
    if(???) {
        return o.toString();
    } else {
        // fallback method
        return o.getClass().getSimpleName();
    }

}

旁注:

这是一个事件总线系统,有些类可以订阅,然后根据实现的接口接收事件。我不可能要求所有客户端都使用toString(),而且我希望将此方法用于此目的之外。

4 个答案:

答案 0 :(得分:14)

如果使用Object getClass()方法,则可以使用该类并调用getMethod().getDeclaringClass()方法。如果是Object,则不会覆盖它。否则,沿线的某个地方被覆盖。 Source

答案 1 :(得分:1)

此处检查对象中是否有toString方法:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TemplateHelper {

    public static void main(String [] args){
        int a = 3;
        try {
            objToString(a);
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public static void objToString(Object object) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException{
        Class c = object.getClass();
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            if(method.getName().equals("toString")){
                System.out.println(method.getName()); //THERE IS toString in object
                break;
            }
        }
    }

}

答案 2 :(得分:0)

也许这有点傻但你可以试试:

    String objToString(Object o)
{
    if(!(o.toString().contains("@" + o.hashCode()))) {
        return o.toString();
    } else {
        // fallback method
        return o.getClass().getSimpleName();
    }

}

或者只是简化版本:

String objToString(Object o) {
  if (o.toString().equals(
      o.getClass().getName() + "@" + Integer.toHexString(o.hashCode()))) {
    // fallback method
    return o.getClass().getSimpleName();
  } else {
    return o.toString();
  }
}

答案 3 :(得分:0)

以下是如何使用反射来解决问题的方法。使用反射在您收到的对象中查找toString方法。如果它是在java.lang.Object中声明的,那么请使用您自己的方法。

import java.lang.reflect.Method;
import java.util.Random;

public class ToStringUtils {
    public static String myToString(Object o) {
        if (o == null)
            return "null";
        if (overridesToString(o.getClass()))
            return o.toString();
        // Replacement for Object.toString()
        return o.getClass().getSimpleName() + "@" + System.identityHashCode(o);
    }

    public static boolean overridesToString(Class<?> clazz) {
        Method m;
        try {
            m = clazz.getMethod("toString");
        } catch (NoSuchMethodException e) {
            // Can't be thrown since every class has a toString method through Object
            return false;
        }
        return (m.getDeclaringClass() != Object.class);
    }

    // Small demo
    public static void main(String[] args) {
        System.out.println(myToString(new Integer(5)));
        System.out.println(myToString(new Random()));
    }
}