任何对象的java toString
我有很多数据对象,我希望能够生成表示每个对象的String
,而不需要为每个对象实现toString
方法。
我正在考虑获取字段及其值的reflection。
还有其他想法吗?
谢谢。
欢迎您使用雅加达的ToStringBuilder。 它有2种模式,一种是需要使用API添加所需的所有字段,另一种是基于reflection:
@Override public String toString() { return ToStringBuilder.reflectionToString(this); }
使用JUtils插件在包级别生成toString方法
或者使用reflection你可以尝试这样的事情:
public static void toString(Object object) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException{ Class c = object.getClass(); Method[] methods = c.getMethods(); for (Method method : methods) { if(method.getName().startsWith("get")){ System.out.println(method.getName()+" -> " +method.invoke(object, null)); } } }
JUtil插件是最好的,因为如果您需要提供有关该对象的更多信息,这将允许您稍后更改对象的toString。
如果你有很多对象,那么不是在每个类中添加toString
而是使用代码检测(你可以在jar中改变.class或者在加载时使用javaagent更改它们)。 例如, AspectJ会有所帮助,但还有很多其他选择。 例如,你可以做这样的事情(使用来自Apache Commons的 AspectJ和ToStringBuilder ):
@Aspect public class ToStringAspect { @Around("execution(String *.toString()) && target(t) && within(your.target.package.*)") public String toStringCall(Object t) { return ToStringBuilder.reflectionToString(t); } }
ToStringBuilder非常灵活。 例如,如果您不需要通过设置StandardToStringStyle#setUseClassName(false)来使用类名称使用样式:
public String toStringCall(Object t) { StandardToStringStyle style = new StandardToStringStyle(); style.setUseClassName(false); style.setUseIdentityHashCode(false); ToStringBuilder builder = new ReflectionToStringBuilder(t, style); return builder.toString(); }
实现toString方法的方法很少。
-
思考(Apache库)
@Override public String toString(){ return org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(this); }
-
基于JSON的实现(GSON,Jackson库)
// GSON library for JSON @Override public String toString(){ return new com.google.gson.Gson().toJson(this); } // Jackson libabry for JSON/YAML @Override public String toString() { try { return new com.fasterxml.jackson.databind.ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this); } catch (com.fasterxml.jackson.core.JsonProcessingException e) { e.printStackTrace(); } return null; }
-
ToStringBuilder(与apache-commons库一起提供)
@Override public String toString() { return new org.apache.commons.lang3.builder.ToStringBuilder(this). append("field1", field1). append("field2", field2). toString(); }
-
硬核toString()实现
@Override public String toString() { return new StringBuilder() .append("field1:"+field1) .append("field2:"+field2) .toString(); }
toString
方法由Java中的每个Classinheritance,来自java.lang.Object
。 我看不出你怎么能避免不实现(实际上覆盖) Object.toString
。 此外,为每个类定义方法,而不是为每个对象定义方法。
您可以使用inheritance层次结构来解决此问题,方法是让您的类inheritance自覆盖默认toString
实现的公共类。 此实现可以使用reflection来反映类的字段(不是父类,但实际上是当前对象的类),并生成字符串。
如果您根本不想覆盖该方法,也可以调查字节码编织的使用。 就个人而言,我认为投入字节码编织的努力并不值得,特别是当你可以覆盖toString
。
某种静态String dataToString(Data data)
方法可能有效。 我没有任何反思的知识,所以这是我的想法。
方法实现取决于数据对象的设置方式。 inheritance还在继续吗? 如果存在,则可以将超类型对象作为参数传入,并对所有数据全局使用该方法。 您需要在方法中执行一些条件检查或其他forms的逻辑,具体取决于您的程序设置的准确程度,以返回正确的字符串。
有关您的程序的更多信息(如何设置,您想要打印什么,数据对象是什么等)将帮助我更好地回答这个问题:)
如果要为每个对象实现toString(),可以使用AspectJ。 除此之外,你将无法为每个对象实现该方法。
如前所述,您可以使用已经实现的库,如Apache commons-lang的ReflectionToStringBuilder 。 如上所述。
或者用reflectionAPI自己写smt。
这是一些例子 :
class ReflectionAnalyzer { private ArrayList