当前位置: 首页 > 知识库问答 >
问题:

Lambda vs Anon vs静态嵌套类

申屠宏胜
2023-03-14

这个类有三个方法执行相同的操作,它们等待页面加载三秒钟,如果页面加载,则返回true。
我的问题是,我如何决定哪段代码是最好的?
我知道Lambda比Anon类更好,但为什么静态嵌套类(pageLoaded3)不好呢?根据这篇文章,它也应该是合适的。

public final class ExpectedConditions {

    private ExpectedConditions() {
    }

    public static ExpectedCondition<Boolean> pageLoaded1() {
        return (driver) -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return !((JavascriptExecutor) driver).executeScript("return performance.timing.loadEventEnd", new Object[0])
                    .equals("0");
        };
    }

    public static ExpectedCondition<Boolean> pageLoaded2() {
        return new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver driver) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return !((JavascriptExecutor) driver)
                        .executeScript("return performance.timing.loadEventEnd", new Object[0]).equals("0");
            }
        };
    }

    public static ExpectedCondition<Boolean> pageLoaded3() {
        return new PageLoaded();
    }

    private static class PageLoaded implements ExpectedCondition<Boolean> {
        @Override
        public Boolean apply(WebDriver driver) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return !((JavascriptExecutor) driver).executeScript("return performance.timing.loadEventEnd", new Object[0])
                    .equals("0");
        }
    }

}

这是三个方法返回类型的接口:

public interface ExpectedCondition<T> extends Function<WebDriver, T> {}

共有1个答案

谭敏学
2023-03-14

正如评论中已经提到的:功能相当。所以从技术上来说,差别是边际的。所有方法都编译成类似的字节码。所以关于哪一个是“最好”的问题只能从代码本身来回答。在这方面,可以采用不同的标准。

首先,正如Peter Lawrey在评论中所建议的:您可以将thread.sleep调用拉出到一个helper方法中:

private static void pause(long ms)
{
    try
    {
        Thread.sleep(ms);
    }
    catch (InterruptedException e)
    {
        Thread.currentThread().interrupt();
    }
}

此外,您可以将在那里实现的核心功能提取到一个helper方法中:

private static Boolean execute(WebDriver driver)
{
    pause(3000);
    return !((JavascriptExecutor) driver)
        .executeScript("return performance.timing.loadEventEnd", new Object[0])
        .equals("0");
}
public static ExpectedCondition<Boolean> pageLoaded4()
{
    return ExpectedConditions::execute;
}
  1. 带有lambda
  2. 具有匿名类
  3. 具有静态innner类
  4. 具有方法引用

从实际意义上讲,人们可以争论利弊:

>

  • 方法3,带有静态innner类:这不是必需的。如果静态内部类只是一个方法调用的包装器,那么它并不起到真正的作用。它引入了一个新名称(在您的例子中为PageLoaded)和源代码中的一个新间接--这意味着程序员必须查找PageLoaded类来查看它的功能。在其他情况下,情况可能不同。例如。如果PageLoaded类有其他方法或字段,但这里不是这样。

    方法1,使用lambda:这是在Java8中实现这样一个功能接口的标准方法。就我个人而言,我更喜欢拥有短小的lambda身材。就像你问题中的那个

    return (driver) -> {
        // "Many" lines of code, maybe even nested, with try-catch blocks
    };
    

    是不是IMHO不是那么可读性和简洁,我通常会尽量让这些身体保持尽可能短。在最好的情况下,{括号}可以省略--但有疑问,可以通过引入包含lambda主体的方法来省略。在这种情况下,人们通常可以把它归结为最后一种方法:

    方法4,带有方法参考。它可能有点主观,但我认为这是最易读的。该方法的优点是它是一个“构建块”,具有清晰的功能,可以在JavaDocs中明确指定。此外,您甚至可以考虑省略包装方法(上面称为PageLoaded4),而将该方法作为public方法提供。以前调用的用户

    ExpectedCondition<Boolean> condition = 
        ExpectedConditions::pageLoaded4();
    

    然后可以直接使用该方法

    ExpectedCondition<Boolean> condition = 
        ExpectedConditions::execute;
    

  •  类似资料:
    • 问题内容: 什么是静态嵌套类?静态和非静态嵌套类有什么区别? 问题答案: 静态内部类是嵌套在具有修饰符的另一个类中的类。除了可以访问在其内部定义的类的私有成员之外,它与顶级类几乎相同。 类是静态内部类。类是一个非静态的内部类。两者之间的区别是,非静态内部类的实例被永久连接到的实例-你不能创建一个没有。不过,您可以独立创建对象。 中的代码,并且都可以访问x; 不允许使用其他代码。

    • 问题内容: 我很难用Java的非静态嵌套类来解决问题。考虑以下示例,该示例先显示“ Inner”,然后显示“ Child”。 我知道Inner实例始终必须与Outer实例相关联,这也适用于Child,因为它扩展了Inner。我的问题是语法的含义- 为什么调用内部构造函数? 我只看到一个用于调用超类构造函数和调用重写方法的超类版本的纯文本,但从未使用过这种形式。 问题答案: 这称为“合格的超类构造函

    • 我正在用Java建模,并使用构建器模式。在许多情况下,一些共同成员是在父级中定义的,而其他成员则是在从父级继承的子级上定义的。一个例子如下: 如果删除,则在上得到相同的错误。看来我对静态嵌套类的继承有一个根本的误解。 为什么当返回时,编译器会抱怨方法不在中?有没有一种方法可以像我所尝试的那样,利用继承和这个构建器模式,允许在父级中定义公共成员,在子级中定义其他成员?

    • 我有以下java代码: 我的问题如下:我收到一个文本和一种语言,我必须检查该文本是否仅使用该语言的有效字母字符书写。我的代码如下: 这很好,也很有效,但随着我在应用程序中添加语言,我将不得不在交换机中添加越来越多的案例。 我想知道在中是否有一种方法可以动态命名一个静态嵌套类,比如: 所以我上面的代码可能是这样的: 谢谢,如果这是超级简单的事情,我很抱歉。 我是一名开发人员,正在学习。

    • 问题内容: 我正在查看Java代码,并注意到它使用了静态嵌套类。 使用静态嵌套类而不是普通内部类的原因是什么? 我能想到的唯一原因是Entry不能访问实例变量,因此从OOP的角度来看,它具有更好的封装性。 但是我认为可能还有其他原因,也许是性能。可能是什么? 注意。我希望我的术语正确,可以将其称为静态内部类,但是我认为这是错误的:http : //java.sun.com/docs/books/t

    • 我有以下示例类<code>Foo</code>和嵌套类<code<Bar</code<,所有内容都是<code>constexpr</code>: 我想测试调用<code>Foo::DoTheThing</code>返回1: 海湾合作委员会和Clang都在这里抱怨,但MSVC没有 GCC表示: 错误: ,或者如果我将< code>Bar的定义移到< code>Foo之外,我可以让GCC和Clang