2015-02-11 51 views
2

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

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

如果参数不是一个对象而是一个基本变量会怎么样?

如果它是一个像String这样的不可变Object。谢谢。

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 

那么,这是否意味着,即使我们不指定这个参数设置为一个局部变量它仍然有效?

回答

2

我不认为分配给theExpected可以实现任何功能。

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

可能您链接的帖子的作者认为这个显式样式更具可读性。

+0

嗨@henry,我只是做了一个小测试,证明你是对的吗? – 2015-02-11 15:55:11

1

不要紧,如果theExpected是原始或对象(尽管在这个例子中它是一个对象),以及是否是可变与否。

matches方法返回延伸BaseMatcher(并实现Matcher接口,假设它是接口)的匿名类的实例。

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

+0

谢谢你的解释。我现在得到了这个。 如果这与Matcher或inner类无关,它只是普通类中的普通公共方法。我们还会这样做吗?谢谢。 – 2015-02-11 15:09:13

+0

@TechNoob好吧,有一些setter方法用于修改类的成员,所以在这种情况下,您仍然会将传递的参数分配给实例变量。另一方面,其他方法使用它们的参数一次,并且不存储它(例如,请参阅代码中'matches'方法的'o'参数)。 – Eran 2015-02-11 15:13:08

+0

@Eran虽然期望移出范围,但它指向的对象仍然存在,并且它仍然有效,可以从匿名类中访问'expected'。我不相信分配给Expected会提供任何功能性的用途 - 预计可以直接使用。 – henry 2015-02-11 15:23:21

1

如果您希望/需要在内部类(本例中为匿名本地类)中使用局部变量,则无论该变量是基元类型还是引用类型,该变量都必须声明为final。这里最好解释一下:Why Java inner classes require "final" outer instance variables?。引用最好的解释国际海事组织:

语言坚持的原因是它作弊,以便提供您的内部类功能访问他们渴望的本地变量。运行时会制作本地执行上下文(如适用)的副本,因此它坚持要求所有内容都是最终的,以便保持诚实。

如果它不这样做,那么,改变局部变量的值,构建你的对象之后,但在内部类之前函数运行可能会造成混乱和怪异的代码。

在这种情况下,似乎作者想保留发送给该方法的参数的副本,该参数是为进一步评估而生成的匿名类的参考。一旦该方法完成其执行,参数Object expected不再可用,所以如果你想/需要保留它,那么你必须将它分配到你的类的一个领域。

+0

但该参数被声明为final。我想这个问题是“为什么不直接写'expected.equals(o)'? – RealSkeptic 2015-02-11 15:01:10

+0

@RealSkeptic我仍然在写答案,我倾向于写东西,发布它,然后编辑以添加更多信息 – 2015-02-11 15:05:10

+0

谢谢我现在得到了这个,而@RealSkeptic在这里有一个很好的观点,我也希望听到你的意见,如果这与内部类没有关系,它只是一个普通的公共方法正常的类谢谢 – 2015-02-11 15:08:20

相关问题