java传入通用泛型_java泛型

1         泛型

1.1            泛型的作用

泛型有两种作用,一种是让接口或方式更通用,一种是限制作用。

第一种是一种是让接口或方式更通用,泛型和C++的模板很相似,有时在定义函数或者接口时,不确定需要传入的参数是什么类型,这时可能要创建多个重载函数来枚举所有的数据类型。而有了泛型之后,直接用一个标识符代替具体的数据类型,在调用的时候传入具体的数据类型给标识符。从而实现接收任意数据类型的方法。例如:

public interface Generator {

public T next();

}

第二则是限制作用。例如创建List时是以Object作为基类,所以可以放入任何类型的对象List arrayList = new ArrayList();arrayList.add("aaaa");arrayList.add(100);但是在输出的时候,不知道输出是什么类型。使用不当会导致奔溃。所以需要通过泛型来限制输入数据的类型。List arrayList = new ArrayList();只能输入String类型的数据,其他类型数据则会报错。

1.2            泛型的使用

1.2.1             泛型类

泛型类的定义

public class Generic{

//key这个成员变量的类型为T,T的类型由外部指定

private T key;

public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定

this.key = key;

}

public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定

return key;

}

}

泛型对象的创建

//泛型的类型参数只能是类类型(包括自定义类),不能是简单类型

//传入的实参类型需与泛型的类型参数类型相同,即为Integer.

Generic genericInteger = new Generic(123456);

Log.d("泛型测试","key is " + genericInteger.getKey());

也可以省略泛型形参,会根据输入的数据类型自动识别。

Generic generic2 = new Generic(55.55);

Generic generic3 = new Generic(false);

1.2.2             泛型接口

定义泛型接口:

public interface Generator {

public T next();

}

实现泛型接口

(1)不指定泛型类型,实现类中也要加入泛型标识

class FruitGenerator implements Generator{

@Override

public T next() {

return null;

}

}

(2)指定泛型类型,实现类中无需泛型标识

public class FruitGenerator implements Generator {

private String[] fruits = new String[]{"Apple", "Banana", "Pear"};

@Override

public String next() {

Random rand = new Random();

return fruits[rand.nextInt(3)];

}

}

1.2.3             泛型方法

首先在public与返回值之间的必不可少,这表明这是一个泛型方法,

public T showKeyName(Generic container){

System.out.println("container key :" + container.getKey());

//当然这个例子举的不太合适,只是为了说明泛型方法的特性。

T test = container.getKey();

return test;

}

在泛型类中者形参中带有泛型标识符public void showKeyValue1(T key) ;showKeyValue1(Generic obj);带有通配符的函数 public void showKeyValue2(Generic> obj);或返回值是泛型标识符public T getKey();这些都不算是真正的泛型方法。其中的泛型标识符是类的泛型标识符,创建对象时传入实际的数据类型,调用泛型方法时,必须传入创建对象时的泛型数据类型。泛型类中泛型方法声明泛型标识符T可以与泛型类的泛型标识符T一样,也可以换成E,或者其他标识符。泛型方法中的标识符在泛型方法调用时,传入实际的数据类型,与泛型类中的标识符T没有必然联系,例如泛型类传入的类型是String,并不代表泛型方法中的T也是String类型。而是在泛型方法调用时传入具体的数据类型。总之泛型标识符只是用来标识,由传入数据类型决定。

1.2.4             泛型可变参数

泛型也可以用于可变参数:

public void printMsg( T... args){

for(T t : args){

Log.d("泛型测试","t is " + t);

}

}

printMsg("111",222,"aaaa","2323.4");//传入不同类型的变量。

1.2.5             静态方法与泛型

因为静态方法属于类,而不属于对象,所有无法使用创建对象传入泛型的数据类型。所以静态方法如果要用泛型的话,只能定义为泛型方法。在静态方法调用时,传入具体的数据类型。

public class StaticGenerator {

//public static void show(T t){..};ERROR此时编译器会提示错误信息:

public static void show(T t){ }};

1.2.6             泛型通配符?

Ingeter是Number的一个子类,Ingeter变量可以传给Number。但是Generic变量却不可以传给Generic,不是子类和父类关系。这样就无法传递,因此类型通配符云而生。

public void showKeyValue1(Generic> obj);

使用?代替具体的类型实参,可以把?看成所有类型的父类。任何类型的Generic、Generic、Generic等都可以传入,Generic>各种泛型的父类,但是只能作为泛型形参,不能创建对象保存数据。可以解决不确定具体类型时,直接用?号代替;但同时也引入另外一个问题,因为不确定是什么类型,所在方法中只使用Object类中的基本功能方法。不可以用传入类型的特殊的方法。

1.2.7             泛型的边界

泛型的作用是能够传入任意数据类型,但是有时需要限制输入的类型范围,例如只允许number的子类传入。这时就需要设置边界;

public void showKeyValue1(Generic extends Number> obj);

这样只有Number的子类构成的变量Generic、Generic等才可以传人,而Generic则不能传入。这就是边界。

泛型类也可以设置边界:

public class Generic{};

泛型方法也可以设置边界:

public T showKeyName(Generic container){};

1.2.8             泛型数组

Java是不支持泛型数组的,也就是说下面的这个例子是不可以的:

List[] ls = new ArrayList[10];

那么为什么不可以呢?来看一个例子:

List[] lsa = new List[10]; // 实际是不可行,先假设可以这样.

Object o = lsa;//创建一个object引用指向数组

Object[] oa = (Object[]) o;

List li = new ArrayList();//新建一个Integer的 List

li.add(new Integer(3));//加入一个数据

oa[1] = li; // 将list赋值给数组的第一个元素

String s = lsa[1].get(0); //这里会报异常

由于JVM泛型的擦除机制,在运行时JVM是不知道泛型信息的,所以可以给oa[1]赋上一个ArrayList而不会出现异常,但是在取出数据的时候却要做一次类型转换,所以就会出现ClassCastException,如果可以进行泛型数组的声明,上面说的这种情况在编译期将不会出现任何的警告和错误,只有在运行时才会出错。所以无法创建指定类型的泛型数组,可以采用通配符的方式创建数组:

List>[] lsa = new List>[10]; // OK, array of unbounded wildcard type.

Object o = lsa;

Object[] oa = (Object[]) o;

List li = new ArrayList();

li.add(new Integer(3));

oa[1] = li; // Correct.

Integer i = (Integer) lsa[1].get(0); // OK

因为使用了通配符,所以获取数据后需要进行强制类型转换,就不会出错。

自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:

百度云盘下载地址:

链接:https://pan.baidu.com/s/1swkQzCIKI3g3ObcebgpIDg

提取码:mc8l

微信公众号获取最新的软件和视频介绍

QStockView

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对你的问题,我来给你解答一下。 在Java中,是一种用于编写可重用代码的机制,可以让你在编译时检测类安全性。通过使用,我们可以编写出更加通用的代码,提高代码的复用性和可读性。 在Java中,参数可以传入类、接口和方法中。在方法中传入参数时,可以使用以下几种方式: 1. 传入具体类参数 例如,假设我们有一个方法: ```java public <T> void print(T t) { System.out.println(t); } ``` 我们可以通过以下方式传入具体类参数: ```java print("hello world"); // 传入String类参数 print(123); // 传入Integer类参数 ``` 2. 传入参数 在某些情况下,我们可能需要在方法中传入参数。此时,可以使用以下方式: ```java public <T> void printList(List<T> list) { for (T t : list) { System.out.println(t); } } ``` 在调用该方法时,我们可以传入任何类的List: ```java List<String> stringList = Arrays.asList("hello", "world"); List<Integer> intList = Arrays.asList(1, 2, 3); printList(stringList); // 传入String类的List printList(intList); // 传入Integer类的List ``` 3. 传入通配符类参数 有时候,我们可能需要在方法中传入一个不确定类的List。此时,可以使用通配符类参数: ```java public void printList(List<?> list) { for (Object obj : list) { System.out.println(obj); } } ``` 在调用该方法时,我们可以传入任何类的List: ```java List<String> stringList = Arrays.asList("hello", "world"); List<Integer> intList = Arrays.asList(1, 2, 3); printList(stringList); // 传入String类的List printList(intList); // 传入Integer类的List ``` 注意,使用通配符类参数时,我们只能对List进行读取操作,不能进行添加或删除操作。 希望这些内容能够解答你的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值