Java中的奇数方法调用,使用点运算符访问泛型列表

2022-09-01 13:02:45

我遇到了一些高级java代码(对我来说:)高级)我需要帮助理解。

在类中有一个嵌套类,如下所示:

private final class CoverageCRUDaoCallable implements
        Callable<List<ClientCoverageCRU>>
{
    private final long oid;
    private final long sourceContextId;

    private CoverageCRUDaoCallable(long oid, long sourceContextId)
    {
        this.oid = oid;
        this.sourceContextId = sourceContextId;
    }

    @Override
    public List<ClientCoverageCRU> call() throws Exception
    {
        return coverageCRUDao.getCoverageCRUData(oid, sourceContextId);
    }
}

稍后在外部类中,有一个正在创建的可调用类的实例。我不知道这是什么:

ConnectionHelper.<List<ClientCoverageCRU>> tryExecute(coverageCRUDaoCallable);

对我来说,它看起来不像java语法。你能详细说说这个神秘的语法中发生了什么吗?您可以在下面的代码摘录中看到它被使用。

CoverageCRUDaoCallable coverageCRUDaoCallable = new CoverageCRUDaoCallable(
        dalClient.getOid(), sourceContextId);

// use Connection helper to make coverageCRUDao call.
List<ClientCoverageCRU> coverageCRUList = ConnectionHelper
        .<List<ClientCoverageCRU>> tryExecute(coverageCRUDaoCallable);

EDITED 添加了 ConnectionHelper 类。

public class ConnectionHelper<T>
{
    private static final Logger logger =
        LoggerFactory.getLogger(ConnectionHelper.class);

    private static final int    CONNECTION_RETRIES = 3;

    private static final int    MIN_TIMEOUT        = 100;

    public static <T> T tryExecute(Callable<T> command)
    { 
        T returnValue = null;
        long delay = 0;

        for (int retry = 0; retry < CONNECTION_RETRIES; retry++)
        { 
            try
            { 
                // Sleep before retry
                Thread.sleep(delay);

                if (retry != 0)
                {
                    logger.info("Connection retry #"+ retry);
                }

                // make the actual connection call
                returnValue = command.call();
                break;

            } 
            catch (Exception e)
            {
                Throwable cause = e.getCause();
                if (retry == CONNECTION_RETRIES - 1)
                {
                    logger.info("Connection retries have exhausted. Not trying "                        
                            + "to connect any more.");

                    throw new RuntimeException(cause);
                }

                // Delay increased exponentially with every retry.
                delay = (long) (MIN_TIMEOUT * Math.pow(2, retry));

                String origCause = ExceptionUtils.getRootCauseMessage(e);

                logger.info("Connection retry #" + (retry + 1)
                        + " scheduled in " + delay + " msec due to "
                        + origCause);
                        + origCause);
            }
        }
        return returnValue;
    }

答案 1

您通常认为类是泛型的,但方法也可以是泛型的。一个常见的例子是Arrays.asList

大多数时候,您不必使用带有尖括号的语法,即使您调用泛型方法也是如此,因为这是Java编译器在某些情况下实际上能够进行基本类型推断的一个地方。例如,文档中给出的代码段省略了类型:<...>Arrays.asList

List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");

但它等效于此版本,其中显式给出了泛型类型:

List<String> stooges = Arrays.<String>asList("Larry", "Moe", "Curly");

答案 2

这是因为,在 Java 7 之前,泛型并不完全支持目标类型,因此您需要在 编译器上稍微帮助编译器使用一些类似于 .ConnectionHelper.<List<ClientCoverageCRU>>

但请注意,Java 8 显著改进了目标类型,在特定示例中,Java 8 中不需要类型见证。


推荐