2

我正在阅读本网站的教程。http://tutorials.jenkov.com/java-unit-testing/matchers.html 相信作者很有经验。我看到了这样的代码。我还看到其他人总是喜欢将方法的参数分配给变量,然后在方法中使用它。这就是这条线。protected Object theExpected = expected;

谁能告诉我,这种编码风格有什么好处?这是试图避免改变对象状态还是什么?

如果参数不是对象而是原始变量怎么办。

如果它是像 String 这样的不可变对象呢?谢谢你。

public static Matcher matches(final Object expected){

    return new BaseMatcher() {

        protected Object theExpected = expected;

        public boolean matches(Object o) {
            return theExpected.equals(o);
        }

        public void describeTo(Description description) {
            description.appendText(theExpected.toString());
        }
    };
}

这是更新

我刚刚又做了一个测试,看看我们得到对象后这个参数是否仍然可以访问。

package myTest;


public class ParameterAssignTest {

    public static void main(String[] args) {
        MyInterface myClass = GetMyClass("Here we go");
        System.out.println(myClass.getValue());
        System.out.println(myClass.getParameter());
    }

    public static MyInterface GetMyClass(final String myString){

        return new MyInterface() {

            protected String stringInside  = myString;

            @Override
            public String getValue() {
                return stringInside;
            }

            @Override
            public String getParameter() {
                return myString;
            }
        };
    }
}

输出:

Here we go
Here we go

那么这是否意味着即使我们将此参数分配给局部变量它仍然有效?

4

3 回答 3

2

我不相信分配来theExpected取得任何成就。

正如预期的那样,它可以在匿名类中访问。如果它直接在describeTo对象中使用,则不会被 GC,并且当expected声明的本地范围离开时,引用将保持有效。

您链接到的帖子的作者可能认为这种明确的风格更具可读性。

于 2015-02-11T15:10:55.307 回答
1

不管theExpected是原始的还是对象的(尽管在这个例子中它是一个对象),以及它是否是可变的都没有关系。

matches方法返回一个匿名类的实例,该类扩展BaseMatcher(并实现Matcher接口,假设它是一个接口)。

一旦它返回实例,expected传递给它的局部变量 - - 就超出了范围,但是theExpected包含与该局部变量相同的值的成员保留在实例中,并且可以被该实例的方法使用。

于 2015-02-11T14:59:16.187 回答
1

如果您想/需要在内部类(在这种情况下为匿名本地类)中使用局部变量,则必须将变量声明为final无论它是原始类型还是引用类型。在这里可以更好地解释:为什么 Java 内部类需要“最终”外部实例变量?. 引用 IMO 的最佳解释:

该语言坚持这样做的原因是它作弊是为了让您的内部类函数能够访问他们渴望的局部变量。运行时会制作本地执行上下文的副本(以及适当的等),因此它坚持您将所有内容都设为最终版本,以便它可以保持诚实。

如果它没有这样做,那么在构造对象之后但在内部类函数运行之前更改局部变量值的代码可能会令人困惑和奇怪。

在这种情况下,似乎作者希望在生成的匿名类的引用中保留发送给方法的参数的副本以供进一步评估。一旦方法完成执行,参数Object expected就不再可用,所以如果你想/需要保留它,那么你必须将它分配到你的类的一个字段中。

于 2015-02-11T14:59:59.593 回答