我有一个棘手的Java库任务。

我需要编写一个用于处理JTable的适配器/帮助程序类,如果JTable 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 ... */
}

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

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

最佳答案

您可以测试:

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

if( cls != null )
    // have JXTable

之后,您必须专门使用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 );
    }
}

Java VM在本身不使用但仅存在于jar文件中的类中使用不存在的API不会出现问题。使用这种方法,仅当org.jdesktop.swingx.JXTable可用时,才使用JXTableHandler,否则,则使用StdTableHandler。

08-08 00:10