java.util.regex.Pattern 和 java.util.regex.Matcher 的设计有什么好处?

What is benefit in design of java.util.regex.Pattern and java.util.regex.Matcher?

好像java.util.regex.Pattern和java.util.regex.Matcher是聚合关系,我觉得。而java API 表示在下面使用它们。

Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();

为什么Pattern和Matcher是通过静态方法初始化的?放置这种可能性有什么好处?它是否直接在我的源上对调用创建者不利?

为什么Pattern是用static工厂方法创建的?

根据 documentation of Pattern

A (Pattern) is compiled representation of a regular expression.

一个Pattern对象将与一个模式相关联,并且该对象的用户应该创建一次并多次使用它。通过提供静态工厂,Pattern class 可以在 returning Pattern 对象之前自由执行内部检查。例如,如果在对 compile 的另一个调用中提供了相同的模式字符串,它可以(如果它希望)缓存 Pattern 实例和 return 缓存的实例(注意:这不是虽然它的实现方式,但是,由于使用静态工厂,它具有这种自由。

为什么Matcher是在Pattern上通过工厂方法创建的?

Matcher一举两得
(以下为方便讨论的简化透视图,详情请参考Java doc of Matcher:

  1. 检查给定的字符串是否与给定的正则表达式匹配。
  2. 将给定的字符串与给定的模式进行匹配,return 各种匹配结果。

对于第一种情况,可以使用Pattern.matches(regex, string)形式的方法调用。在这种情况下,正则表达式将被编译,布尔结果将在匹配后 returned。请注意,这是一种 functional 编程风格 - 它在这里工作正常,因为没有要维护的匹配状态。

对于第二种情况,需要维护一个匹配状态,匹配完成后用户可以查询。因此,在这种情况下,使用 Matcher 对象可以维护匹配结果的状态。由于 Matcher 对象在没有对应的 Pattern 对象的情况下无法存在,因此 API 开发人员仅允许通过 Pattern 的实例创建它 - 因此用户可以调用 p.matcher('aaaaab') .在内部,Pattern class 中的代码如下所示:

public Matcher matcher(CharSequence input) {
    if (!compiled) {
        synchronized(this) {
            if (!compiled)
                compile();
        }
    }
    Matcher m = new Matcher(this, input);
    return m;
}

可以看出,MatcherPattern 作为构造函数参数 - 这样它就可以在不同的点调用它来获取和维护匹配结果

PS
与任何 API 一样,PatternMatcher 的实现方式也可能有所不同 - 并非所有 Java API 的设计都是一致的 - 我猜开发那些 API 的开发人员总是有一些特征被遗忘。以上答案是我对这些开发人员采用的方法的解释。