无论是列表(对象列表)还是List< String> (Strings列表)在Groovy中使用?
在下面的代码示例中,两个列表都是ArrayList(对象的ArrayList).将第二个列表预期为ArrayList< String> (Strings的ArrayList).
当编译类时,Groovy会丢失类型信息,并在编译的类被执行时推断它吗?
实施例1
List untypedList = ["a","b","c"]List<String> typedList = ["a","c"]println "Untyped List List: ${untypedList.getClass()}"println "Typed List List<String>: ${typedList.getClass()}"
输出1
Untyped List List: class java.util.ArrayListTyped List List<String>: class java.util.ArrayList // Would have expected ArrayList<String>
问题2
我本来希望这个行typedList<<下面的示例中的新的整数(1)将失败,因为我试图将一个int放入一个字符串列表中.任何人都可以解释为什么我可以在String类型列表中添加一个int? 输出显示它仍然是一个整数,即它不是即时转换为字符串“1”. 实施例2
List untypedList = ["a","c"]untypedList << new Integer(1)typedList << new Integer(1) // Why does this work? Shouldn't an exception be thrown?println "Types:"println "Untyped List List: ${untypedList.getClass()}"println "Typed List List<String>: ${typedList.getClass()}"println "List contents:"println untypedListprintln typedListprintln "Untyped List:"untypedList.each { println it.getClass() }println "Typed List:"typedList.each { println it.getClass() }
输出2
Types:Untyped List List: class java.util.ArrayListTyped List List<String>: class java.util.ArrayListList contents:[a,b,c,1][a,1]Untyped List:class java.lang.Stringclass java.lang.Stringclass java.lang.Stringclass java.lang.IntegerTyped List:class java.lang.Stringclass java.lang.Stringclass java.lang.Stringclass java.lang.Integer解决方法 在运行Groovy“正常”时,泛型将在编译之前被丢弃,因此只有在源代码中才存在对开发人员的有用提示.
但是,您可以使用@CompileStatic或@TypeChecked来使Groovy符合这些泛型,并在编译时检查事物的类型.
例如,考虑我有以下项目结构:
project |---- src | |---- main | |---- groovy | |---- test | |---- ListDelegate.groovy | |---- Main.groovy |---- build.gradle
用代码:
的build.gradle
apply plugin: 'groovy'repositorIEs { mavenCentral()}dependencIEs { compile 'org.codehaus.groovy:groovy-all:2.2.1'}task( runSimple,dependsOn:'classes',type:javaexec ) { main = 'test.Main' classpath = sourceSets.main.runtimeClasspath}
ListDelegate.groovy
package testclass ListDelegate<T> { @Delegate List<T> numbers = []}
Main.groovy
package testclass Main { static main( args ) { def del = new ListDelegate<Integer>() del << 1 del << 'tim' println del }}
现在,运行gradle runSimple给我们的输出:
:compileJava UP-TO-DATE:compileGroovy:processResources UP-TO-DATE:classes:runSimple[1,tim]BUILD SUCCESSFulTotal time: 6.644 secs
所以你可以看到,泛型被抛弃了,它只是加入了整数和字符串列出了只有整数的列表
现在,如果我们将ListDelegate.groovy更改为:
package testimport groovy.transform.*@CompileStaticclass ListDelegate<T> { @Delegate List<T> numbers = []}
并再次运行:
:compileJava UP-TO-DATE:compileGroovy:processResources UP-TO-DATE:classes:runSimple[1,tim]BUILD SUCCESSFulTotal time: 6.868 secs
我们得到相同的输出!这是因为虽然ListDelegate现在是静态编译的,但我们的Main类仍然是动态的,所以在构造ListDelegate之前仍然会丢弃泛型…所以我们也可以将Main.groovy更改为:
package testimport groovy.transform.*@CompileStaticclass Main { static main( args ) { def del = new ListDelegate<Integer>() del << 1 del << 'tim' println del }}
而现在重新运行毕业生runSimple给我们:
:compileJava UP-TO-DATE:compileGroovystartup Failed:/Users/tyates/Code/Groovy/generics/src/main/groovy/test/Main.groovy: 10: [Static type checking] - Cannot find matching method test.ListDelegate#leftShift(java.lang.String). Please check if the declared type is right and if the method exists. @ line 10,column 9. del << 'tim' ^1 error:compileGroovy Failed
正如你所期望的那样,没有为我们声明的整数列表添加一个String.
其实你只需要CompileStatic的Main.groovy类,这个错误就会被拿起来,但是我总是喜欢使用它,而不是只需要我.
总结以上是内存溢出为你收集整理的列表和列表在Groovy相同?全部内容,希望文章能够帮你解决列表和列表在Groovy相同?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)