Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
类型为T的数组(Java泛型)_Java - Fatal编程技术网

类型为T的数组(Java泛型)

类型为T的数组(Java泛型),java,Java,尽管此代码编译成功,但在运行时会引发类强制转换异常错误: class Test { public static void main(String[] args) { MyArray<String> x = new MyArray<>(); x.a[0] = "test string"; } } class MyArray<T> { T[] a; MyArray() { this

尽管此代码编译成功,但在运行时会引发类强制转换异常错误:

class Test {
    public static void main(String[] args) {
        MyArray<String> x = new MyArray<>();
        x.a[0] = "test string";
    }
}

class MyArray<T> {
    T[] a;

    MyArray() {
        this.a = (T[]) new Object[1];
    }
}
我所知道的一个可能但简单的解决方案是将数组声明为Object类型的数组,然后当您要从数组中检索数组元素时,将其强制转换回T,如下所示:

class Test {
    public static void main(String[] args) {
        MyArray<String> x = new MyArray<>();
        x.a[0] = "test string";
        System.out.println(x.get(0));
    }
}

class MyArray<T> {
    Object[] a;

    MyArray() {
        this.a = new Object[1];
    }

    T get(int index) {
        return (T) a[index];
    }
}
显然,当所有数组元素都是同一类型时要比作为Object类型的泛型对象好得多。一定有办法做到的

顺便说一下,我在这里给出的示例代码已经大大简化了。我知道我可以使用set和get方法来进行必要的类型转换,当然,这将有助于在数组中添加和获取元素。这个问题是,如果我在类中有很多其他方法也做了大量的转换,那么编写所有这些转换操作符的单调乏味将成为一个真正的痛苦。我想如果我可以将数组中的所有元素存储为单词go中的某个类型,那就太好了。这将简化编码过程,使代码更清晰、更易于阅读。所以,任何你想通过我的方式的智慧的话都是最受欢迎的,并且会得到更多的赞赏

但这种方法的问题是,我完全可以在数组中放入任何内容

对。这就是为什么不公开阵列的原因:

class MyArray<T> {
    private Object[] a;

    MyArray() {
        this.a = new Object[1];
    }

    T get(int index) {
        return (T) a[index];
    }

    void set(int index, T value) {
        a[index] = value;
    }
}
但这种方法的问题是,我完全可以在数组中放入任何内容

对。这就是为什么不公开阵列的原因:

class MyArray<T> {
    private Object[] a;

    MyArray() {
        this.a = new Object[1];
    }

    T get(int index) {
        return (T) a[index];
    }

    void set(int index, T value) {
        a[index] = value;
    }
}

ClassCastException发生的原因是。基本上,泛型是完全在编译器中发生的语法糖。因为
T
可以是任何东西,所以数组的运行时类型必须是Object,因为它可以存储任何东西

解决此问题的一种方法是将类传递给构造函数,以便它可以使用它创建具有正确运行时类型的数组:

import java.lang.reflect.Array;
类MyArray{
T[]a;
MyArray(类类型){
this.a=(T[])Array.newInstance(类型,1);
}
T get(int索引){
返回一个[索引];
}
}
你可以这样使用它:

MyArray<String> myStringArray = new MyArray<>(String.class);
MyArray myStringArray=newmyarray(String.class);

不理想,但我认为最不雅观的解决方法。

ClassCastException是由于。基本上,泛型是完全在编译器中发生的语法糖。因为
T
可以是任何东西,所以数组的运行时类型必须是Object,因为它可以存储任何东西

解决此问题的一种方法是将类传递给构造函数,以便它可以使用它创建具有正确运行时类型的数组:

import java.lang.reflect.Array;
类MyArray{
T[]a;
MyArray(类类型){
this.a=(T[])Array.newInstance(类型,1);
}
T get(int索引){
返回一个[索引];
}
}
你可以这样使用它:

MyArray<String> myStringArray = new MyArray<>(String.class);
MyArray myStringArray=newmyarray(String.class);

不太理想,但我认为这是最不雅观的解决方法。

您可以使用对象数组并将其私有化。您还需要创建一个“set”方法,这样您就不能放置任何内容。这就是ArrayList的工作方式

另一个解决方案是使用reflection array类创建T的数组。为此,必须将实际类型类作为参数传递:

class Test {
    public static void main(String[] args) {
        MyArray<String> x = new MyArray<>(String.class);
        x.a[0] = "test string"; // works
        x.a[1] = 1; // does not even compile
    }
}

class MyArray<T> {
    T[] a;

    MyArray(Class<T> clazz) {
        this.a = (T[]) Array.newInstance(clazz, 2);
    }
}
类测试{
公共静态void main(字符串[]args){
MyArray x=新的MyArray(String.class);
x、 [0]=“测试字符串”;//有效
x、 [1]=1;//甚至不编译
}
}
类MyArray{
T[]a;
MyArray(类clazz){
this.a=(T[])Array.newInstance(clazz,2);
}
}

您可以使用对象数组并将其设置为私有。您还需要创建一个“set”方法,这样您就不能放置任何内容。这就是ArrayList的工作方式

另一个解决方案是使用reflection array类创建T的数组。为此,必须将实际类型类作为参数传递:

class Test {
    public static void main(String[] args) {
        MyArray<String> x = new MyArray<>(String.class);
        x.a[0] = "test string"; // works
        x.a[1] = 1; // does not even compile
    }
}

class MyArray<T> {
    T[] a;

    MyArray(Class<T> clazz) {
        this.a = (T[]) Array.newInstance(clazz, 2);
    }
}
类测试{
公共静态void main(字符串[]args){
MyArray x=新的MyArray(String.class);
x、 [0]=“测试字符串”;//有效
x、 [1]=1;//甚至不编译
}
}
类MyArray{
T[]a;
MyArray(类clazz){
this.a=(T[])Array.newInstance(clazz,2);
}
}


当你意识到C++模板在私有化和添加一套方法之后,并不是那么“坏”的时候,你会做些什么来实现什么?这就是ArrayList所做的(你可能想看看这个类的代码)。你在C++实现后,在实现一个私有的并添加一个SET方法之后,意识到C++模板不是那么“坏”的时候,你该怎么做?这就是ArrayList的基本功能(您可能想看看该类的代码)?你能写一个示例代码来说明如何做到这一点吗?我编辑了我的答案,添加了一个用法示例。这正是医生要求的!这是否是一个理想的解决方案是一个悬而未决的问题,或者说是一个过程。但事实是,绝对没有免费的午餐。非常感谢。很高兴听到这个消息!请随意接受我的回答……;)我如何通过“打字”考试?你能写一个示例代码来说明如何做到这一点吗?我编辑了我的答案,添加了一个用法示例。这正是医生要求的!这是否是一个理想的解决方案是一个悬而未决的问题,或者说是一个过程。但事实是,绝对没有免费的午餐。非常感谢。很高兴听到这个消息!请随意接受我的回答……;)如何使用它?@Choletski你是什么意思?我如何将它用于未知类型的数组,以及如何从中获取所需的类型。@Choletski正如我在这里所描述的:创建一个
MyArray
的实例,你有一个封装数组的对象,其中元素保证只包含给定类型的对象。如何使用
class Test {
    public static void main(String[] args) {
        MyArray<String> x = new MyArray<>(String.class);
        x.a[0] = "test string"; // works
        x.a[1] = 1; // does not even compile
    }
}

class MyArray<T> {
    T[] a;

    MyArray(Class<T> clazz) {
        this.a = (T[]) Array.newInstance(clazz, 2);
    }
}