问题描述
我有在Nexus上执行的groovy脚本:
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));
运行该命令后,我得到:
- - - 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
为什么components
不是com.google.common.collect.Iterables
的实例?
我希望我能做:
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();
}
但这会导致错误:
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'
如何强烈键入变量:
def components = null;
?
当我查看Java文档时: https://google. github.io/guava/releases/21.0/api/docs/com/google/common/collect/Iterables.html
它看起来不像com.google.common.collect.Iterables
是java.lang.Iterable
的子类
根据下面的答案,我可以做:
Iterable<Component> components = null;
但是我如何在没有猜测"的情况下找到com.google.common.collect.Iterables$4
?
Iterables
是一个实用工具类(它仅包含静态方法,无法实例化).
我想您的com.google.common.collect.Iterables$4
只是实现 java.lang.Iterable
.
总而言之,将components
定义为Iterable
应该适合您.
编辑:回答您的后续问题:
1)您写道,它看起来不像 Iterables
实现 Iterable
,您说得对-事实并非如此.为了了解com.google.common.collect.Iterables$4
的含义,您需要了解编译命名规则. /docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html"rel =" nofollow noreferrer>匿名类.
简而言之,com.google.common.collect.Iterables$4
表示嵌套在com.google.common.collect.Iterables
类中的第四个匿名类".
2)关于如何找到类型而不进行猜测-您只需跟踪API及其返回的内容即可:
-
Repository.facet
返回给定类型的Facet
(此处为StorageFacet
) -
StorageFacet.txSupplier
返回Supplier<StorageTx>
-
StorageTx.browseComponents
返回Iterable<Component>
请注意,这是上面的所有接口,因此我们仍然看不到如何实现返回的Iterable<Component>
.
要了解这一点,我们需要查看实现: StorageTxImpl
.但是,这将进一步委托调用,而我不希望进一步跟踪它(如果愿意,您可以自己完成;但是,如果在IDE中打开此项目,则要容易得多).
但是,我知道发生了什么情况,即调用了Guava的Iterables
实用工具类中的方法之一,这又返回了通过匿名类实现的Iterable<T>
,仅此而已. /p>
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"?
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:
Repository.facet
returns aFacet
of given type (here:StorageFacet
)StorageFacet.txSupplier
returnsSupplier<StorageTx>
StorageTx.browseComponents
returnsIterable<Component>
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.
这篇关于com.google.common.collect.Iterables和实例类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!