com.google.common.collect.Iterables and the instan

2019-08-17 08:17发布

I have this groovy script that is executed on nexus:

def retentionDays = 30;
def retentionCount = 10;
def repositoryName = 'maven-releases';
def whitelist = ["org.javaee7.sample/javaee7-simple-sample", "org.javaee7.next/javaee7-another-sample"].toArray();

log.info(":::Cleanup script started!");

MaintenanceService service = container.lookup("org.sonatype.nexus.repository.maintenance.MaintenanceService");
def repo = repository.repositoryManager.get(repositoryName);
def tx = repo.facet(StorageFacet.class).txSupplier().get();
def components = null;
try {
    tx.begin();
    components = tx.browseComponents(tx.findBucket(repo));
}catch(Exception e){
    log.info("Error: "+e);
}finally{
    if(tx!=null)
        tx.close();
}

log.info(" - - A - - Type of 'components.getClass().getName()' is: " +  components.getClass().getName());
log.info(" - - B - - Type of 'components' is: " +  components);
log.info(" - - C - - Type of 'components.getClass()' is: " +  components.getClass());
log.info(" - - D - - Type of 'components[0].getClass()' is: " +  components[0].getClass());


log.info(" - - components instanceof com.google.common.collect.Iterables = " + (components instanceof com.google.common.collect.Iterables));

When that is run I get:

     -  - - A - - Type of 'components.getClass().getName()' is: com.google.common.collect.Iterables$4
     -  - - B - - Type of 'components' is: []
     -  - - C - - Type of 'components.getClass()' is: class com.google.common.collect.Iterables$4
     -  - - components instanceof com.google.common.collect.Iterables = false
     -  - - D - - Type of 'components[0].getClass()' is: class org.codehaus.groovy.runtime.NullObject

Why is components not an instance of com.google.common.collect.Iterables ?

I would expect that I could do:

import com.google.common.collect.Iterables
Iterables components = null;
try {
    tx.begin();
    components = tx.browseComponents(tx.findBucket(repo));
}catch(Exception e){
    log.info("Error: "+e);
}finally{
    if(tx!=null)
        tx.close();
}

But that gives the error:

Error: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '[]' with class 'com.google.common.collect.Iterables$4' to class 'com.google.common.collect.Iterables'

How do I strongly type the variable:

   def components = null;

?

When I look at the java docs: https://google.github.io/guava/releases/21.0/api/docs/com/google/common/collect/Iterables.html

its does not look like com.google.common.collect.Iterables is a sub class of java.lang.Iterable

Based on below answer I can do:

Iterable<Component> components = null;

But how do I find that com.google.common.collect.Iterables$4 without "guessing"?

标签: java guava
1条回答
在下西门庆
2楼-- · 2019-08-17 08:57

Iterables is a utility class (it contains only static method and cannot be instantiated).

I guess that your com.google.common.collect.Iterables$4 is just some anonymous class implementing java.lang.Iterable.

To sum up, defining components as Iterable should work for you.


EDIT: To answer your follow-up questions:

1) You wrote that it does not look like Iterables implements Iterable, and you're right - it doesn't. In order to understand what com.google.common.collect.Iterables$4 means you need to understand the compilation naming rules of anonymous classes.

In short, com.google.common.collect.Iterables$4 means "4th anonymous class nested in com.google.common.collect.Iterables class".

2) As to how you find out the type without guessing - you simply track the API and what it returns:

Note that it's all interfaces above, so we still don't see from this how the returned Iterable<Component> is implemented.

To find out about this, we need to see into the implementation: StorageTxImpl. This, however, delegates the call further and I don't feel like tracing it any further (you can do it on your own if you wish; it'd much be easier to do if one opened this project in an IDE, though).

However, I know that what happens there is that a call to one of the methods in Guava's Iterables utility class is made, which in turn returns Iterable<T> implemented by means of an anonymous class, and that's all.

查看更多
登录 后发表回答