Pattern.compile是否缓存?

它可能是一个实现细节,但对于Oracle和IBM JDK,至少是缓存的编译模式还是我们应用程序开发人员需要自己执行编译模式的缓存?

我不相信结果是缓存的,并且在代码或文档中没有这种行为的证据。 它(当然)自己实现这样的缓存是相对微不足道的,但我会对这种缓存有益的用例感兴趣。

回覆。 下面的注释和String.split() ,有一种不同的方法,代码为简单的1或2个char模式与更复杂的regexp采用不同的路径。 但它似乎仍然没有缓存。

据我所知,从查看代码(JDK 6)开始,它不进行缓存,但是一旦构造完成,Pattern对象可以在应用程序端缓存并在多个线程之间共享。 标准模式似乎是将其分配给最终的静态变量:

private static final Pattern p = Pattern.compile(","); 

它没有。 如果您有性能敏感区域,则可能希望将模式对象保存为成员变量。

当你在函数中使用正则表达式时,Clojure会或多或少地自动执行此操作。

我创建了一个可以缓存Pattern对象的类CachedPattern 。 如果运行main方法,您将看到Java的Pattern对象实际上是不同的实例,这也会消耗内存。

 import java.util.HashMap; import java.util.regex.Pattern; import org.eclipse.core.runtime.Assert; public class CachedPattern { public static void main(String[] args){ Pattern p1 = Pattern.compile("abc"); Pattern p2 = Pattern.compile("abc"); Pattern p3 = Pattern.compile("abc"); Pattern p4 = Pattern.compile("abc"); Pattern p5 = Pattern.compile("abc"); Pattern x1 = CachedPattern.compile("abc"); Pattern x2 = CachedPattern.compile("abc"); Pattern x3 = CachedPattern.compile("abc"); Pattern x4 = CachedPattern.compile("abc"); Pattern x5 = CachedPattern.compile("abc"); // are cached objects the same ? YES! Assert.isTrue(x1.equals(x2)); Assert.isTrue(x1.equals(x3)); Assert.isTrue(x1.equals(x4)); Assert.isTrue(x1.equals(x5)); // are non-cached objects the same ? NO! Assert.isTrue(p1.equals(p2)); //AssertionFailedException } private static HashMap cached = new HashMap<>(); /** * This value must be unique, to make sure user won't use this inside "regex" variable, * so that objects without flags would be returned * For example if UNIQUE_HASH would be empty: * compile(pattern = "abc1") * VS. * compile(pattern = "abc", flag = 1) * This would give same keys "abc1" and "abc1" */ private static final String UNIQUE_HASH = "(())[]+@#$%^@!@#$%*"; public static Pattern compile(String regex){ if(cached.containsKey(regex)){ return cached.get(regex); } Pattern p = Pattern.compile(regex); cached.put(regex, p); return p; } public static Pattern compile(String regex, int flags){ String uniqueKey = regex + UNIQUE_HASH + flags; if(cached.containsKey(uniqueKey)){ return cached.get(uniqueKey); } Pattern p = Pattern.compile(regex); cached.put(uniqueKey, p); return p; } }