我应该将Jackson的ObjectMapper声明为静态字段吗?

Jackson图书馆的ObjectMapper类似乎是线程安全的 。

这是否意味着我应该声明我的ObjectMapper像这样的静态字段

 class Me { private static final ObjectMapper mapper = new ObjectMapper(); } 

而不是像这样的实例级别的字段?

 class Me { private final ObjectMapper mapper = new ObjectMapper(); } 

是的,这是安全的,并build议。

您提到的页面中唯一的警告是,一旦共享映射器,您将无法修改映射器的configuration; 但是你并没有改变configuration,所以很好。 如果你确实需要改变configuration,你可以从静态块中做到这一点,这也可以。

编辑 :(2013/10)

在2.0及更高版本中,可以通过注意到还有一个更好的方法来增强上面的内容:使用ObjectWriterObjectReader对象,它们可以由ObjectMapper构造。 它们是完全不可变的,线程安全的,这意味着甚至在理论上也不可能导致线程安全问题(如果代码试图重新configuration实例,这可能发生在ObjectMapper )。

尽pipeObjectMapper是线程安全的,但我强烈build议不要将它声明为静态variables,特别是在multithreading应用程序中。 甚至不是因为这是一个糟糕的做法,而是因为你面临着死锁的重大风险。 我从我自己的经验来讲这个。 我创build了一个具有4个相同线程的应用程序,它们正在从Web服务中获取和处理JSON数据。 根据线程转储,我的应用程序经常停顿在以下命令上:

 Map aPage = mapper.readValue(reader, Map.class); 

除此之外,performance并不理想。 当我用基于实例的variablesreplace静态variables时,失速消失,性能翻了四番。 即240万个JSON文档在40分钟内处理了56秒,而不是2.5小时。

尽pipe在线程安全性方面声明一个静态的ObjectMapper是安全的,但是你应该知道在Java中构造静态的Objectvariables被认为是不好的做法。 有关更多详细信息,请参阅为什么静态variables被视为恶 (如果你愿意, 我的回答 )

简而言之,应该避免静态写入,因为编写简洁的unit testing很困难。 例如,使用静态最终的ObjectMapper,你不能换出JSON序列化的虚拟代码或无操作。

另外,一个静态的final可以防止你在运行时重新configurationObjectMapper。 现在你可能不会想到这样的一个理由,但是如果你将自己locking在一个静态的最终模式中,那么抛弃类加载器就可以让你重新初始化它。

在ObjectMapper的情况下,它的罚款,但一般来说这是不好的做法,并没有优于使用单例模式或控制反转来pipe理您的长寿命的对象。

com.fasterxml.jackson.databind.type.TypeFactory._hashMapSuperInterfaceChain(HierarchicType)

 com.fasterxml.jackson.databind.type.TypeFactory._findSuperInterfaceChain(Type, Class) com.fasterxml.jackson.databind.type.TypeFactory._findSuperTypeChain(Class, Class) com.fasterxml.jackson.databind.type.TypeFactory.findTypeParameters(Class, Class, TypeBindings) com.fasterxml.jackson.databind.type.TypeFactory.findTypeParameters(JavaType, Class) com.fasterxml.jackson.databind.type.TypeFactory._fromParamType(ParameterizedType, TypeBindings) com.fasterxml.jackson.databind.type.TypeFactory._constructType(Type, TypeBindings) com.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeReference) com.fasterxml.jackson.databind.ObjectMapper.convertValue(Object, TypeReference) 

com.fasterxml.jackson.databind.type.TypeFactory类中的方法_hashMapSuperInterfaceChain是同步的。 在高负载下看到了相同的争用。

可能是避免静态ObjectMapper的另一个原因