编写Java库以有条件地处理输入类,而不会对该类造成无条件的运行时依赖性

Jas*_*n S 5 java dependencies jar instanceof classpath

我有一个看似棘手的Java库任务.

我需要编写一个适配器/辅助类来处理JTable具有一些附加功能的s,如果它JTable是a JXTable.但我不想在swingx-core-1.6.2.jar上添加运行时依赖,除非我的应用程序实际使用JXTable(在这种情况下它已经要求在类路径上有SwingX jar文件)

如何解耦我的代码来实现这一目标?我甚至不知道如何测试JXTable; 如果我尝试instanceof JXTable用作测试,这意味着我的代码已经对JXTable具有无条件的运行时依赖性.

我之前编写的Java库有"可选"的运行时链接依赖项:如果我在我的库中有这个:

package com.foobar.foolib;

// import from whizbang.jar
import com.whizbang.BloatwareThingy;

public class SuperObject
{
    /* ... uses a BloatwareThingy ... */
}
Run Code Online (Sandbox Code Playgroud)

并且SuperObject是唯一使用whizbang.jar的类,然后只要我的最终应用程序不使用SuperObject,那么就没有运行时依赖于whizbang.jar; 如果我的最终应用程序确实想要使用SuperObject,那么它需要在类路径中包含whizbang.jar.从应用的角度来看是可选的.效果很好.

如何编写一个方法来测试给定的JTable是否为JXTable的实例,如果应用程序仅使用JTable,则不需要依赖SwingX jar文件?

x4u*_*x4u 5

您可以测试:

Class cls = null;
try {
    cls = Class.forName( "org.jdesktop.swingx.JXTable" );
} catch( Throwable ex ) {}

if( cls != null )
    // have JXTable
Run Code Online (Sandbox Code Playgroud)

之后,您必须专门使用Reflection来访问来自该外部库的类,方法,构造函数和字段.

如果您需要以这种方式访问​​大型API,这可能变得非常笨拙,您可以编写可以直接使用JXTable但通过Reflection创建并通过接口或抽象类调用的辅助类:

public interface MyTableHandler
{
    void doSomethingWithTable( JTable table );
}

public class JXTableHandler implements MyTableHandler
{
    void doSomethingWithTable( JTable table )
    {
        JXTable jxt = (JXTable) table;
        // use JXTable API directly ...
    }
}

public class StdTableHandler implements MyTableHandler
{
    void doSomethingWithTable( JTable table )
    {
        // do without JXTable
    }
}

public class MyIndependentClass
{
    static final MyTableHandler handler;

    static {
        try {
            Class.forName( "org.jdesktop.swingx.JXTable" ); // force exception
            handler = (MyTableHandler) Class.forName( "my.pkg.JXTableHelper" )
                                            .newInstance();
        } catch( Throwable ex ) {
            handler = new StdTableHandler();
        }
    }
    public void treatTable( JTable table )
    {
        handler.doSomethingWithTable( table );
    }
}
Run Code Online (Sandbox Code Playgroud)

Java VM在不使用自身但仅存在于jar文件中的类中使用不存在的API没有问题.使用此方法,仅当org.jdesktop.swingx.JXTable可用时才使用JXTableHandler,否则使用StdTableHandler.


Jam*_*ark 2

这需要反思。用于Class.forName(...)获取 JXTable 类的 Class 对象。如果它不存在,它将抛出ClassNotFoundException

如果存在,您可以使用该 Class 对象来获取所需的方法,然后将它们应用到 JTable 对象。