问题
I'm receiving an Object and need to log it. Some of them have cusom toString() and then I'd like to use that, but some have none and I get something like mightypork.rogue.bus.events.MouseMotionEvent@2d19587d.
I'm looking for a way to dynamically (perhaps with reflection?) check if the incoming object has toString() overridden itself.
String objToString(Object o)
{
if(???) {
return o.toString();
} else {
// fallback method
return o.getClass().getSimpleName();
}
}
Side note:
It's an event bus system, some classes can subscribe and then receive events based on implemented interfaces. I can't possibly require all clients to have toString(), plus I want to use this method for more than this one purpose.
回答1:
If you use the Object getClass() method, you can use the class and invoke the getMethod().getDeclaringClass() method. If it is Object, then it is not overridden. Otherwise, somewhere along the line is was overriden. Source
回答2:
Here to check if you have a toString method in your object :
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;
}
}
}
}
回答3:
Here's how you can use reflection to figure it out. Find the toString method in the object you received using reflection. If it was declared in java.lang.Object, then use your own method.
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()));
}
}
回答4:
Maybe it is silly a bit but u can try that:
String objToString(Object o)
{
if(!(o.toString().contains("@" + o.hashCode()))) {
return o.toString();
} else {
// fallback method
return o.getClass().getSimpleName();
}
}
or just something like that simplified version:
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();
}
}
来源:https://stackoverflow.com/questions/22866925/detect-if-object-has-overriden-tostring