有关java泛型数组的问题,求指点

zeling1005 2015-09-03 01:44:14
LinkedList[] li=new LinkedList[20];
li[9]=new LinkedList();
li[9].add("ASD");

以上代码总是提示要参数化,但是这是泛型数组要怎么参数化啊。我去网上查了,好像是java不支持这样的泛型数组,那要达到上述三行代码的效果是不是有那种替代的代码呢?
...全文
290 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
解开者 2015-09-06
  • 打赏
  • 举报
回复
引用 7 楼 mg2flyingff 的回复:
楼主,泛型是一个编译时期的概念,在运行时是不存在的。它仅仅支持使用泛型过的引用在编译期检查类型,在运行时没有任何检查手段。如果你听说过类型擦除就会了解了。 由上可知,在实际生成的对象中是不存在泛型信息的,所以我们不能生成泛型数组。但是我们可以使用一个泛型引用来引用产生的数组,这样就能使用它提供的类型检查功能了。赋值时的类型转换可以使用SuppressWarinings注解来去掉那个警告信息(这样做反而是安全的)。 当然。泛型是一个比较脆弱的机制,不提供强制检查,需要程序员自觉使用。下面这段代码能体现出一些这种特性:

@SuppressWarnings("unchecked")
LinkedList<String>[] l = new LinkedList[10];
LinkedList<Integer>[] lx = (LinkedList[])l;
l[0] = new LinkedList<>();
l[0].add("ASD");
lx[0].add(1);
System.out.println(lx[0].get(1).intValue());
System.out.println(lx[0].get(0));
它运行时不会报错。
尽量不要使用这种写法,这会影响代码可读性,留下不必要的隐患。比如代码里还有这样一个方法:
void integer(Integer integer) {
	}
在调用integer(lx[0].get(0))的时候将引起转型异常;或者调用lx[0].toArray(new Integer[lx[0].size()])也会引起转型异常。 参数的引用类型是Integer,因此能够通过编译,但实际类型是String,所以无法运行。这是很奇怪的,因为一个被声明为Integer的变量无法作为Integer使用,你将这种代码提供给调用者的时候他们会感到莫名其妙。这种坑在框架中很多,一旦踩坑也很难排查。 我建议用List<List<E>>这种方式,尽可能不用泛型数组。如果是为了兼容旧代码等原因不得不用,可以参考这个 再或者,采用List<?>[] li = new List<?>[10]这种方式声明,警告就没了。如果实在需要在同一个集合中放两种以上类型的对象,不如就这么用,然后在取值的时候进行instanceof检查。对于这种需求,类型检查无法避免,不管是用显示转换、泛型还是反射。
zeling1005 2015-09-06
  • 打赏
  • 举报
回复
感谢各位大大的解惑
zeling1005 2015-09-05
  • 打赏
  • 举报
回复
引用 10 楼 mg2flyingff 的回复:
[quote=引用 8 楼 u014532217 的回复:] [quote=引用 6 楼 gam2046 的回复:] [quote=引用 4 楼 u014532217 的回复:] [quote=引用 1 楼 gam2046 的回复:] 这个代码有什么问题吗?可以正常运行的
可以是可以运行,但是有警告。而且从JDK1.5就可以支持泛型了,感觉用了泛型易懂也不用出错,并且用了泛型之后很多地方你都不用强制性转型了。但是泛型数组的话,我就不知道怎么解决了。[/quote] 比如,你的数组是String类型的,你就申明LinkedList<String>,整型LinkedList<Integer>,就是LinkedList<>的形式,你希望是什么类型的数组,就在尖括号里写类型,如果什么都不写,就是Object类型。[/quote] 一般情况下这样是没错的,但是java“不支持”泛型数组(因为有类型擦除,所以不支持)[/quote] 楼主又受误导。泛型这个东西本来就是只存在于编译期,java只是不能声明泛型数组的实例,而不是不支持以泛型数组的方式引用实例。按照你的逻辑“运行时不存在就是不支持”,那java就不支持泛型,连c++也不支持泛型。[/quote] 刚学java一个月,不是很理解,有些东西看的云里雾里的
zeling1005 2015-09-05
  • 打赏
  • 举报
回复
引用 11 楼 gam2046 的回复:

class Array<T>{
	private T[]arrays;
	public T[] getArrays() {
		return arrays;
	}
}
这样算么
我只是想实现这样的功能而已。。。。

package genericsarrays.main;

import java.util.*;

public class GenericsArrays {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		LinkedList<String>[] st=new LinkedList[10];
		st[0]=new LinkedList<String>();//从代码中就可以看出之后要存的是String类型
		st[0].add("ASD");
		String s=st[0].getFirst();//不用做强制类型转换
		System.out.println(s);
	}
/*	public void f(){
		LinkedList[] st=new LinkedList[10];
		st[0]=new LinkedList();
		st[0].add("ASD");
		String s=st[0].getFirst();不能自动的从 Object 转换为 String
		System.out.println(s);
	}*/
}
至于你的这个代码,原谅我才刚学java,不是很理解。但是我还是觉得应该在类构造器初始化数组,或者定义一个方法得到初始化数组,类似于这样(stackoverflow看到的):

public class GenSet<E> {

    private E[] a;

    public GenSet(Class<E> c, int s) {
        // Use Array native method to create array
        // of a type only known at run time
        @SuppressWarnings("unchecked")
        final E[] a = (E[]) Array.newInstance(c, s);
        this.a = a;
    }

    E get(int i) {
        return a[i];
    }
}
zeling1005 2015-09-05
  • 打赏
  • 举报
回复
引用 14 楼 gam2046 的回复:
泛型本身就是基于多态实现,换而言之,肯定存在类型转换,只不过不要求编程人员显式的类型转换而已。 而你的目的我并没有理解,既然要实现这样的功能,那你代码都写出来了,不就是已经实现了么?如果你非要用数组实现,那就把LinkedList换成ArrayList就好了,两者区别就是数据结构不同,一个用数组,一个用链表。 [quote=引用 12 楼 u014532217 的回复:] [quote=引用 11 楼 gam2046 的回复:]

class Array<T>{
	private T[]arrays;
	public T[] getArrays() {
		return arrays;
	}
}
这样算么
我只是想实现这样的功能而已。。。。

package genericsarrays.main;

import java.util.*;

public class GenericsArrays {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		LinkedList<String>[] st=new LinkedList[10];
		st[0]=new LinkedList<String>();//从代码中就可以看出之后要存的是String类型
		st[0].add("ASD");
		String s=st[0].getFirst();//不用做强制类型转换
		System.out.println(s);
	}
/*	public void f(){
		LinkedList[] st=new LinkedList[10];
		st[0]=new LinkedList();
		st[0].add("ASD");
		String s=st[0].getFirst();不能自动的从 Object 转换为 String
		System.out.println(s);
	}*/
}
至于你的这个代码,原谅我才刚学java,不是很理解。但是我还是觉得应该在类构造器初始化数组,或者定义一个方法得到初始化数组,类似于这样(stackoverflow看到的):

public class GenSet<E> {

    private E[] a;

    public GenSet(Class<E> c, int s) {
        // Use Array native method to create array
        // of a type only known at run time
        @SuppressWarnings("unchecked")
        final E[] a = (E[]) Array.newInstance(c, s);
        this.a = a;
    }

    E get(int i) {
        return a[i];
    }
}
[/quote][/quote] 这个实现方式是在这个帖子发了一两天之后才在网上找到的
forDream_ 2015-09-05
  • 打赏
  • 举报
回复
泛型本身就是基于多态实现,换而言之,肯定存在类型转换,只不过不要求编程人员显式的类型转换而已。 而你的目的我并没有理解,既然要实现这样的功能,那你代码都写出来了,不就是已经实现了么?如果你非要用数组实现,那就把LinkedList换成ArrayList就好了,两者区别就是数据结构不同,一个用数组,一个用链表。
引用 12 楼 u014532217 的回复:
[quote=引用 11 楼 gam2046 的回复:]

class Array<T>{
	private T[]arrays;
	public T[] getArrays() {
		return arrays;
	}
}
这样算么
我只是想实现这样的功能而已。。。。

package genericsarrays.main;

import java.util.*;

public class GenericsArrays {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		LinkedList<String>[] st=new LinkedList[10];
		st[0]=new LinkedList<String>();//从代码中就可以看出之后要存的是String类型
		st[0].add("ASD");
		String s=st[0].getFirst();//不用做强制类型转换
		System.out.println(s);
	}
/*	public void f(){
		LinkedList[] st=new LinkedList[10];
		st[0]=new LinkedList();
		st[0].add("ASD");
		String s=st[0].getFirst();不能自动的从 Object 转换为 String
		System.out.println(s);
	}*/
}
至于你的这个代码,原谅我才刚学java,不是很理解。但是我还是觉得应该在类构造器初始化数组,或者定义一个方法得到初始化数组,类似于这样(stackoverflow看到的):

public class GenSet<E> {

    private E[] a;

    public GenSet(Class<E> c, int s) {
        // Use Array native method to create array
        // of a type only known at run time
        @SuppressWarnings("unchecked")
        final E[] a = (E[]) Array.newInstance(c, s);
        this.a = a;
    }

    E get(int i) {
        return a[i];
    }
}
[/quote]
0萌萌哒0 2015-09-04
  • 打赏
  • 举报
回复
楼主,泛型是一个编译时期的概念,在运行时是不存在的。它仅仅支持使用泛型过的引用在编译期检查类型,在运行时没有任何检查手段。如果你听说过类型擦除就会了解了。 由上可知,在实际生成的对象中是不存在泛型信息的,所以我们不能生成泛型数组。但是我们可以使用一个泛型引用来引用产生的数组,这样就能使用它提供的类型检查功能了。赋值时的类型转换可以使用SuppressWarinings注解来去掉那个警告信息(这样做反而是安全的)。 当然。泛型是一个比较脆弱的机制,不提供强制检查,需要程序员自觉使用。下面这段代码能体现出一些这种特性:

@SuppressWarnings("unchecked")
LinkedList<String>[] l = new LinkedList[10];
LinkedList<Integer>[] lx = (LinkedList[])l;
l[0] = new LinkedList<>();
l[0].add("ASD");
lx[0].add(1);
System.out.println(lx[0].get(1).intValue());
System.out.println(lx[0].get(0));
它运行时不会报错。
forDream_ 2015-09-04
  • 打赏
  • 举报
回复

class Array<T>{
	private T[]arrays;
	public T[] getArrays() {
		return arrays;
	}
}
这样算么
0萌萌哒0 2015-09-04
  • 打赏
  • 举报
回复
引用 8 楼 u014532217 的回复:
[quote=引用 6 楼 gam2046 的回复:] [quote=引用 4 楼 u014532217 的回复:] [quote=引用 1 楼 gam2046 的回复:] 这个代码有什么问题吗?可以正常运行的
可以是可以运行,但是有警告。而且从JDK1.5就可以支持泛型了,感觉用了泛型易懂也不用出错,并且用了泛型之后很多地方你都不用强制性转型了。但是泛型数组的话,我就不知道怎么解决了。[/quote] 比如,你的数组是String类型的,你就申明LinkedList<String>,整型LinkedList<Integer>,就是LinkedList<>的形式,你希望是什么类型的数组,就在尖括号里写类型,如果什么都不写,就是Object类型。[/quote] 一般情况下这样是没错的,但是java“不支持”泛型数组(因为有类型擦除,所以不支持)[/quote] 楼主又受误导。泛型这个东西本来就是只存在于编译期,java只是不能声明泛型数组的实例,而不是不支持以泛型数组的方式引用实例。按照你的逻辑“运行时不存在就是不支持”,那java就不支持泛型,连c++也不支持泛型。
hh_ll 2015-09-04
  • 打赏
  • 举报
回复
提示就提示吧,对对吗没有影响。
zeling1005 2015-09-04
  • 打赏
  • 举报
回复
引用 6 楼 gam2046 的回复:
[quote=引用 4 楼 u014532217 的回复:] [quote=引用 1 楼 gam2046 的回复:] 这个代码有什么问题吗?可以正常运行的
可以是可以运行,但是有警告。而且从JDK1.5就可以支持泛型了,感觉用了泛型易懂也不用出错,并且用了泛型之后很多地方你都不用强制性转型了。但是泛型数组的话,我就不知道怎么解决了。[/quote] 比如,你的数组是String类型的,你就申明LinkedList<String>,整型LinkedList<Integer>,就是LinkedList<>的形式,你希望是什么类型的数组,就在尖括号里写类型,如果什么都不写,就是Object类型。[/quote] 一般情况下这样是没错的,但是java“不支持”泛型数组(因为有类型擦除,所以不支持)
forDream_ 2015-09-04
  • 打赏
  • 举报
回复
引用 4 楼 u014532217 的回复:
[quote=引用 1 楼 gam2046 的回复:] 这个代码有什么问题吗?可以正常运行的
可以是可以运行,但是有警告。而且从JDK1.5就可以支持泛型了,感觉用了泛型易懂也不用出错,并且用了泛型之后很多地方你都不用强制性转型了。但是泛型数组的话,我就不知道怎么解决了。[/quote] 比如,你的数组是String类型的,你就申明LinkedList<String>,整型LinkedList<Integer>,就是LinkedList<>的形式,你希望是什么类型的数组,就在尖括号里写类型,如果什么都不写,就是Object类型。
zeling1005 2015-09-03
  • 打赏
  • 举报
回复
引用 2 楼 lonrence 的回复:
泛型主要解决的是1、解决向集合中安全存放元素的问题;2、解决从集合中取元素时需要强转的问题 你看API或者源代码 类名是LinkedList<E>,参数化泛型就是要将E实例化,比如LinkedList<String>,意思是这个LinkedList里存放的是String类型。直接使用LinkedList,会有警告,但不是错误。 你可以这个声明
 LinkedList<LinkedList<String>> li = new LinkedList<LinkedList<String>>();
这个代码我也有考虑过,但是接下去我不知道怎么让它工作,因为我需要的是一个LinkedList数组,然后做:
li[0]=new LinkedList<String>();
li[0].add("ASD")
类似这样的工作的。
zeling1005 2015-09-03
  • 打赏
  • 举报
回复
引用 1 楼 gam2046 的回复:
这个代码有什么问题吗?可以正常运行的
可以是可以运行,但是有警告。而且从JDK1.5就可以支持泛型了,感觉用了泛型易懂也不用出错,并且用了泛型之后很多地方你都不用强制性转型了。但是泛型数组的话,我就不知道怎么解决了。
sxiaobei 2015-09-03
  • 打赏
  • 举报
回复
你想要数组挂链表吗?ArrayList<LinkedList<String>>
  • 打赏
  • 举报
回复
泛型主要解决的是1、解决向集合中安全存放元素的问题;2、解决从集合中取元素时需要强转的问题 你看API或者源代码 类名是LinkedList<E>,参数化泛型就是要将E实例化,比如LinkedList<String>,意思是这个LinkedList里存放的是String类型。直接使用LinkedList,会有警告,但不是错误。 你可以这个声明
 LinkedList<LinkedList<String>> li = new LinkedList<LinkedList<String>>();
forDream_ 2015-09-03
  • 打赏
  • 举报
回复


这个代码有什么问题吗?可以正常运行的

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧