我在自己的个人图书馆中使用SikuliX's API。这个想法是在包含我需要的SikuliX部分的外部项目中单独引用我的库。

现在,SikuliX引发了我需要的FindFailed异常。我试着做:

public class FindFailed extends org.sikuli.script.FindFailed {
    FindFailed(String msg) { super(msg); }
}

这似乎是有道理的。但是,当尝试在其中一种方法中使用throws语句时:
import org.mylibrary.exceptions.FindFailed;

public static boolean clickFinishButton() throws FindFailed {
    pattern = PatternManager.loadPattern("my-image.png");

    screen.wait(pattern, 10);
    region = screen.exists(pattern);
    region.click(pattern);

    return true;
}

我仍然收到Unhandled exception type FindFailed警告。将其更改回原始org.sikuli.script.FindFailed当然可以工作,但是在外部项目中使用try-catch将需要我重新添加相关的SikuliX jar文件。

我想做的就是简单地包装SikuliX抛出的FindFailed异常,并在我的库中在内部和外部使用它。

所有这些的主要目标是用我自己的其他方法来包装另一个API,这样,当我引用该库时,以后的项目也不必引用SikuliX的jar。
- - - - My Library - - - <—————— External Project
|                      |
|        SikuliX       |
- - - - - - - - - - - -

就目前而言,我需要执行以下操作:
- - - - My Library - - - <—————— External Project
|                      |                |
|        SikuliX       |                |
- - - - - - - - - - - -                 v
                                  SikuliX (Again)

到目前为止,我已经更改了如下内容,但似乎可行。
public class FindFailed extends Exception {
    public FindFailed(Throwable cause) { super(cause); }
}

我现在不扩展任何第三方例外。相反,我继续执行以下操作:
public static boolean clickNewScan() throws FindFailed {
    pattern = PatternManager.loadPattern("my-image.png");
    region = screen.exists(pattern);
    try {
        screen.wait(pattern, 60);
        region.click(pattern);
    } catch (org.sikuli.script.FindFailed e) {
        throw new FindFailed(e);
    }
    return true;
}

最佳答案

为此,您可以将SikuliX中的所有调用包装在它们自己的接口中。我不知道SikuliX,所以我将举一个玩具示例。

package third.party.library;

public class Foo {
    public void doSomething() throws ThirdPartyException {
        // Their code
    }
}

好的,因此您想包装此功能而不依赖于它们的库。
package juxhin;

public interface FooBehavior {
    public void doSomething() throws MyException;
}

然后,当您需要它们的行为时,可以使用自己的实现:
package juxhin; // YOU write this class

public class ThirdPartyFooBehavior implements FooBehavior {
    private final Foo foo;

    public FooThirdPartyFooBehavior(Foo theirObject) {
        this.foo = theirObject;
    }

    @Override
    public void doSomething() throws MyException {
        try {
            foo.doSomething();
        } catch (ThirdPartyException e) {
            throw new MyException(e);
        }
    }
}

一旦将它们的库包装在所有自己的接口后面,则您的类将仅取决于您自己的接口,这意味着您不必担心它们的异常。只要您使用非依赖实现重新实现这些接口,它们的库就可以完全删除。

请注意,MyException 不应扩展third.party.library.ThirdPartyException,因为这不会帮助您解决问题。它应该使用 Exception(Throwable cause) 构造函数并将其从org.sikuli.script类层次结构中删除。

但最重要的是,您仍然必须以某种方式包括SikuliX中包含的代码。这就是为什么存在诸如Maven之类的工具的原因,因此将引用添加到jar中非常容易。例如,如果您的jar依赖于SikuliX,那么当您告诉新项目使用jar时,它将自动包含SikuliX参考,而无需您对进行任何操作。您最终会得到像这样的依赖树,它们会自动为您完成所有这些工作:

java - 为什么即使添加引发,包装异常仍仍要求try-catch?-LMLPHP

我个人使用Maven,但还有其他选项(例如IvyGradle)也可以做同样的事情-我不是在这里提倡使用任何特定工具,而只是主张使用任何依赖项工具。

09-07 08:03