我正在研究这一时期的仿制药,今天我已经为我找到了这个谜.
让我们考虑以下虚拟类:
public class Main{
public static void main(String[] args) {
Container<Integer> c = new Container<Integer>();
c.getArray(); //No Exception
//c.getArray().getClass(); //Exception
//int a = c.getArray().length; //Exception
}
}
class Container<T> {
T[] array;
@SuppressWarnings("unchecked")
Container() {
array = (T[])new Object[1];
}
void put(T item) {
array[0] = item;
}
T get() { return array[0]; }
T[] getArray() { return array; }
}
Run Code Online (Sandbox Code Playgroud)
由于擦除,在运行时,getArray()方法的T []返回类型变为Object [],这对我来说是完全合理的.
如果我们按原样访问该方法(c.getArray())没有抛出异常,但是如果我们尝试在返回的数组上调用某些方法,例如c.Array().getClass(),或者如果我们尝试访问一个字段,例如c.getArray().length,然后抛出以下异常:
线程"main"中的异常java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为[Ljava.lang.Integer;
为什么抛出此异常?为什么不对简单的c.getArray()调用抛出它?如果我们只是调用getClass()或访问长度,它为什么要尝试强制转换为Integer []?对于[],getClass()和长度是否也不可用?
在此先感谢您的许多(我希望)和解释(我也希望这样)答案.
基于文档(4.7.6 - 深入了解特定依赖关系),我们可以获得指定配置本身的特定配置的见解.在他们使用的示例中compile
,不推荐使用配置.我试图重现相同的命令置换,以build.gradle
中,compile
与配置implementation
配置(如我,我们不应该用compile
了).但是当我跑步时:
gradle dependencyInsight --dependency groovy --configuration implementation
Run Code Online (Sandbox Code Playgroud)
Gradle正在回归:
Execution failed for task ':dependencyInsight'.
Resolving configuration 'implementation' directly is not allowed
Run Code Online (Sandbox Code Playgroud)
我的build.gradle
文件如下:
apply plugin: 'java-library'
repositories {
jcenter()
}
dependencies{
implementation 'org.codehaus.groovy:groovy-all:2.4.10'
}
Run Code Online (Sandbox Code Playgroud)
这是否意味着如果我正在使用implementation
或者是否有另一种获取方式,我无法获得依赖关系的洞察力?
假设我们有以下程序:
class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}
public class Main {
public static void main(String[] args) {
Fruit[] fruit = new Apple[10];
try {
fruit[0] = new Fruit(); // ArrayStoreException
fruit[0] = new Orange(); // ArrayStoreException
} catch(Exception e) { System.out.println(e); }
}
}
Run Code Online (Sandbox Code Playgroud)
基于Java文档:
抛出以指示已尝试将错误类型的对象存储到对象数组中.
我在这里读到了
创建数组时,它会记住它要存储的数据类型.
如果数组记住它包含的数据类型,则意味着它知道它包含的数据类型.但是我发布的代码片段是正确编译的,所以在编译时,数组显然不知道包含什么类型.
我的问题是:
为什么ArrayStoreException
只在运行时抛出?
编译器缺少哪些信息来实现该分配是不可能的?
ArrayStoreException
抛出?我知道如果我想从 Main 类运行 main,通过使用sourceSets.main.runtimeClasspath
类路径,我必须将 Main 类放在里面src/main/java
并使用类似的东西:
apply plugin: 'java'
dependencies {
}
task myTask (type: JavaExec){
dependsOn classes
classpath sourceSets.main.runtimeClasspath
main = 'Main'
}
Run Code Online (Sandbox Code Playgroud)
我想要的是了解如何指定不同的类路径,从中检索包含 main() 的类。如果我想从不在 src/main/java 中但与build.gradle
.
我知道做这样的事情没有意义,但我希望找到一个解决方案作为学习 Gradle的练习。