解决 Java 中 Generic Array Creation 错误
本篇文章通过代码示例说明了 generic array creation 错误,并重点介绍了创建通用数组时出现此错误的原因。 本次讨论将得出解决方案,我们将学习如何使用对象数组和反射功能创建通用数组。
Java中 Generic Array Creation 错误的演示
示例代码(DemoGenArray.java 类):
import java.util.Arrays;
public class DemoGenArray<T> {
private T[] genericArray;
DemoGenArray(int size) {
genericArray = new T[size];//<----This Line Has Generic Array Creation Error
}
public T get(int index) {
return (T) genericArray[index];
}
public void set(int index, T item) {
genericArray[index] = item;
}
@Override
public String toString() {
return Arrays.toString(genericArray);
}
}
在此类中,我们尝试创建并初始化具有指定数组大小的通用数组。 此外,我们将元素添加到数组中,并从给定索引中单独返回项目。
toString()
立即返回整个数组。
问题是我们在构造函数中指出的行出现了通用数组创建错误。 让我们探讨一下导致此错误的可能原因,这将有助于我们找到解决方案。
Java 中 generic array creation 错误的可能原因
我们试图在代码中创建一个通用数组,这在 Java 中是不可能的。 这是因为 Java 有意识地决定显式地停止这些语法的工作。
请记住,在 Java 中数组是协变的(我们可以将子类型分配给其超类型引用),而泛型则不然。
private T[] genericArray;
genericArray = new T[size];
上面两行代码与下面给出的代码相同。 您可以使用其中任何一个。
private T[] genericArray = new T[size];
这是由于 Java 实现的类型擦除而发生的。 它是由Java编译器执行的一个过程。
它删除泛型中的参数化类型并将它们映射到字节代码中的原始类型。
请记住,字节码没有任何有关泛型的详细信息。 使用类型 T 在编译时没问题,但在运行时没有任何意义。
通过其他方式,我们可以通过下面的代码示例来规避此限制。 下面让我们逐一了解一下。
消除 Java 中 generic array creation 错误的可能解决方案
我们已经知道,编译器在运行时没有任何有关参数化类型的信息。 因此,每当我们需要使用泛型时,最好优先使用 Java Collections 框架的列表组件,而不是使用数组。
然而,我们仍然可以创建类似数组的泛型结构,但这个解决方案取决于它是选中还是未选中。 如果未选中,我们将使用对象数组。
在勾选的情况下,我们可以使用Java的reflect功能。 让我们看看它们各自是如何工作的。
解决方案1:使用对象数组
示例代码(DemoGenArray.java 类):
import java.util.Arrays;
public class DemoGenArray<T> {
private Object[] genericArray;
DemoGenArray(int size) {
genericArray = new Object[size];
}
public T get(int index) {
return (T) genericArray[index];
}
public void set(int index, T item) {
genericArray[index] = item;
}
@Override
public String toString() {
return Arrays.toString(genericArray);
}
}
示例代码(GenArray.java 类)
public class GenArray {
public static void main(String[] args) {
DemoGenArray<String> strArray = new DemoGenArray(3);
strArray.set(0, "one");
strArray.set(1, "two");
strArray.set(2, "three");
DemoGenArray<Integer> intArray = new DemoGenArray(3);
intArray.set(0, 10);
intArray.set(1, 20);
intArray.set(2, 30);
DemoGenArray<Double> doubleArray = new DemoGenArray(3);
doubleArray.set(0, 15.0);
doubleArray.set(1, 110.0);
doubleArray.set(2, 10.0);
System.out.println("Integer Array: " + intArray);
System.out.println("String Array: " + strArray);
System.out.println("Double Array: " + doubleArray);
}
}
输出:
Integer Array: [10, 20, 30]
String Array: [one, two, three]
Double Array: [15.0, 110.0, 10.0]
这里,我们使用 Object 数组来模拟通用数组,因为 DemoGenArray 类是未选中的(弱类型)。 如果我们知道不会对作为参数传递的对象执行类型检查,则可以使用此方法。
此外,我们使用通用的 get()
和 set()
方法分别返回值和设置值。 get()
方法使用显式转换为 T,其中 T 充当泛型的占位符并表示任何值/元素。
如果我们使用 set()
和 get()
方法并且不让用户直接访问对象数组,则效果很好。 来到 GenArray 类,其中包含 main()
方法。
在这里,我们创建 DemoGenArray 类的实例。
我们在实例化 DemoGenArray 类并填充它们时传递所需的类型。 之后,我们使用 toString() 方法写入所有实例的内容。
解决方案2:使用reflect功能
示例代码(DemoGenArray.java 类):
import java.lang.reflect.Array;
import java.util.Arrays;
public class DemoGenArray<T> {
private T[] genericArray;
DemoGenArray(Class<T> classType, int size) {
genericArray = (T[]) Array.newInstance(classType, size);
}
public T get(int index) {
return (T) genericArray[index];
}
public void set(int index, T item) {
genericArray[index] = item;
}
@Override
public String toString() {
return Arrays.toString(genericArray);
}
}
示例代码(GenArray.java 类):
public class GenArray {
public static void main(String[] args) {
DemoGenArray<String> strArray = new DemoGenArray(String.class, 3);
strArray.set(0, "one");
strArray.set(1, "two");
strArray.set(2, "three");
DemoGenArray<Integer> intArray = new DemoGenArray(Integer.class, 3);
intArray.set(0, 10);
intArray.set(1, 20);
intArray.set(2, 30);
DemoGenArray<Double> doubleArray = new DemoGenArray(Double.class, 3);
doubleArray.set(0, 15.0);
doubleArray.set(1, 110.0);
doubleArray.set(2, 10.0);
System.out.println("Integer Array: " + intArray);
System.out.println("String Array: " + strArray);
System.out.println("Double Array: " + doubleArray);
}
}
输出:
Integer Array: [10, 20, 30]
String Array: [one, two, three]
Double Array: [15.0, 110.0, 10.0]
在这里,我们使用反射类来创建通用数组,其类型仅在运行时才知道。 此解决方案与解决方案 1 类似,但 DemoGenArray 类中有两处不同。
首先,我们在 DemoGenArray 类中有一个构造函数,它接受两个参数:数组的类型和大小。 其次,我们使用 Array.newInstance()
方法初始化 genericArray。
Array.newInstance()
方法使用给定的维度(数组的大小)和组件类型创建一个新数组。
相关文章
Java 错误 Java.Net.SocketException: Network Is Unreachable
发布时间:2023/07/16 浏览次数:963 分类:Java
-
今天我们就来讨论一下Java编程时出现java.net.SocketException: Network is unreachable异常的可能原因及解决方法。Java中出现java.net.SocketException: Network is unreachable的可能原因及解决方案
Java 错误 Java.Net.ConnectException: Connection Timed Out
发布时间:2023/07/16 浏览次数:235 分类:Java
-
本篇文章将重点介绍如何使用此包进行基本的网络调用以及可能面临和解决的错误。在 Java 中使用 java.net 进行网络调用 进行网络调用是 Java 开发人员每天面临的最重要的事情之一。
Java 中错误 Attempt to Invoke Virtual Method on a Null Object Reference
发布时间:2023/07/16 浏览次数:948 分类:Java
-
本篇文章介绍如何解决 Java 中的 Attempt to invoke virtual method on a null object reference 错误。Java 中 Attempt to invoke virtual method on a null object reference 错误
Java 错误 Java.Security.InvalidKeyException: Illegal Key Size
发布时间:2023/07/15 浏览次数:644 分类:Java
-
本篇文章介绍包含 java.security.InvalidKeyException: Illegal key size 的 Java 代码。 然后,我们将了解其可能的原因。最后,它通过消除指定的错误来引导我们找到解决方案。
Java 错误 Java.SQL.SQLException: Access Denied for User Root@Localhost
发布时间:2023/07/15 浏览次数:165 分类:Java
-
本篇文章介绍如何解决 Java 中的 java.sql.SQLException: Access Denied for user 'root'@'localhost' 错误。修复 Java 中的 java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
Java 错误 Gateway Process Exited Before Sending Its Port Number
发布时间:2023/07/15 浏览次数:885 分类:Java
-
本篇文章介绍了 Java 中 Java gateway process exited before sending the driver its port number 错误 Java gateway process exited before sending the driver its port number 错误
修复 Java 中 Java.Net.BindException: Address Already in Use: Bind 错误
发布时间:2023/07/15 浏览次数:250 分类:Java
-
本篇文章介绍了 Java 中的 java.net.BindException:Address already in use: Bind 错误。修复Java 中的 java.net.BindException:Address already in use: Bind
Java 中错误 Unsupported Major Minor Version
发布时间:2023/07/14 浏览次数:133 分类:Java
-
出现 Unsupported Major.minor version 错误或 Java.lang.UnsupportedClassVersionError 的原因是运行时 JDK 较低,编译时 JDK 较高。 本篇文章介绍如何解决Java中不支持的major.minor版本。
Java 错误 Error:Java: Javactask: Source Release 1.8 Requires Target Release 1.8
发布时间:2023/07/14 浏览次数:274 分类:Java
-
在使用IntelliJ for Java时,无法编译Java程序是一个常见的问题。 本教程提供了此错误的解决方案。Error:Java: Javactask: Source Release 1.8 Requires Target Release 1.8 错误