I came across some advanced java code (advanced for me :) ) I need help understanding.
In a class there is a nested class as below:
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);
}
}
Later in the outer class, there is an instance of the callable class being created. I have no idea what this is:
ConnectionHelper.<List<ClientCoverageCRU>> tryExecute(coverageCRUDaoCallable);
It doesn't look like java syntax to me. Could you please elaborate what's going on in this cryptic syntax? You can see it being used below in the code excerpt.
CoverageCRUDaoCallable coverageCRUDaoCallable = new CoverageCRUDaoCallable(
dalClient.getOid(), sourceContextId);
// use Connection helper to make coverageCRUDao call.
List<ClientCoverageCRU> coverageCRUList = ConnectionHelper
.<List<ClientCoverageCRU>> tryExecute(coverageCRUDaoCallable);
EDITED added the ConnectionHelper class.
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;
}
Dot operator is a syntactic element, i.e. it denotes the separation between class and package, method and class, variable and reference variable. It can also be called as separator operator.
It is also known as separator or period or member operator. It is used to separate a variable and method from a reference variable. It is also used to access classes and sub-packages from a package. It is also used to access the member of a package or a class.
(dot) operator is used to access class, structure, or union members. The member is specified by a postfix expression, followed by a . (dot) operator, followed by a possibly qualified identifier or a pseudo-destructor name. (A pseudo-destructor is a destructor of a nonclass type.)
You more often think of classes as being generic, but methods can be generic too. A common example is Arrays.asList
.
Most of the time, you don't have to use the syntax with angle brackets <...>
, even when you're invoking a generic method, because this is the one place in which the Java compiler is actually capable of doing basic type inference in some circumstances. For example, the snippet given in the Arrays.asList
documentation omits the type:
List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
But it's equivalent to this version in which the generic type is given explicitly:
List<String> stooges = Arrays.<String>asList("Larry", "Moe", "Curly");
That is because, until Java 7, generics do not fully support target typing, so you need to help the compiler a little with what is called a type witness like in ConnectionHelper.<List<ClientCoverageCRU>>
.
Note however that Java 8 significantly improves target typing and in your specific example the type witness is not required in Java 8.
It's ugly, but valid.
Whatever ConnectionHelper
is, it has a static tryExecute
method that needs to infer a generic type.
Something like:
public static <T> T tryExecute() { ... }
Edit from updated Question: Java has type inference for generic types. The first <T>
in the method signature signifies the type will be inferred when the method is called.
In your updated post you show tryExecute()
defined to take a generic argument:
public static <T> T tryExecute(Callable<T> command)
This actually means the use of that syntax is completely redundant and unnecessary; T
(the type) is inferred from the command
being passed in which has to implement Callable<T>
. The method is defined to return something of the inferred type T
.
Infer a type
|
v
public static <T> T tryExecute(Callable<T> command)
^ ^
| |
<-return type--------------------------
In your example, coverageCRUDaoCallable
has to be implementing Callable<List<ClientCoverageCRU>>
because the method is returning List<ClientCoverageCRU>
In my example above you'd have to use the syntax you were asking about because nothing is being passed in from which to infer the type. T
has to be explicitly provided via using ConnectionHelper.<List<ClientCoverageCRU>>tryExecute()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With