Java泛型

为何要使用泛型?
首先我们以ArrayList为例,在使用ArrayList的时候常会遇到两个问题
1,当获取一个值的时候必须进行强制类型转换
2,当向其中放入值的时候没有约束只要是对象就行了
所以对数据操作失误便会引起程序报错,于是我们可以使用泛型提供的类型参数来解决这个问题
ArrayList<String> arr = new ArrayList<String>();
此时编译器在我们使用get()方法时自动知道返回的是String类型,不需要我们去进行类型转换,同样当我们去使用add()方法时编译器也会知道要添加的数据为String类型

一,泛型类
定义:具有一个或者多个的类型变量的类,称之为泛型类。

package test;

public class Person<T> {
   
  private T t;
 
  public void add(T t) {
    this.t = t;
  }
 
  public T get() {
    return t;
  }
 
  public static void main(String[] args) {
	  Person<Integer> integerP = new Person<Integer>();
	  Person<String> stringP = new Person<String>();
 
	  integerP.add(new Integer(6));
	  stringP.add(new String("复仇者联盟"));
 
    System.out.println("组织成员有 :" + integerP.get() + "人");
    System.out.println("这个组织是 :" + stringP.get());
  }
}

二,泛型方法:所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前,每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。

package test;

public class MethodTest{
   // 泛型方法 printArray                         
   public static < E > E add( E[] numbers ){
      // 输出数组元素            
	  return numbers[0];
    }
 
    public static void main( String args[] ){
        // 创建整型数组: Integer
        Integer[] numbers = { 1, 2, 3, 4, 5 };
        System.out.println( "整型数组元素为:" + add(numbers));
 
    } 
}

下面的例子演示了"extends"如何使用在一般意义上的意思"extends"(类)或者"implements"(接口)。该例子中的泛型方法返回三个可比较对象的最大值。

package test;

public class MaximumTest
{
   // 比较三个值并返回最大值
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // 假设x是初始最大值
      if ( y.compareTo( max ) > 0 ){
         max = y; //y 更大
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // 现在 z 更大           
      }
      return max; // 返回最大对象
   }
   public static void main( String args[] )
   {
      System.out.printf( "%d, %d 和 %d 中最大的数为 %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );
 
      System.out.printf( "%.1f, %.1f 和 %.1f 中最大的数为 %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
 
      System.out.printf( "%s, %s 和 %s 中最大的数为 %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}

三,类型通配符:类型通配符一般是使用?代替具体的类型参数。例如 List<?> 在逻辑上是List<String>,List<Integer> 等所有List<具体类型实参>的父类。

package test;

import java.util.ArrayList;
import java.util.List;

public class GenericTest {
    
    public static void main(String[] args) {
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();
        
        name.add("icon");
        age.add(18);
        number.add(314);
 
        //getUperNumber(name);//1此处会报错,因为getUperNumber()方法中的参数已经限定了参数泛型上限为Number
        getUperNumber(age);//2
        getUperNumber(number);//3
       
   }
 
   public static void getData(List<?> data) {
      System.out.println("data :" + data.get(0));
   }
   
   public static void getUperNumber(List<? extends Number> data) {
          System.out.println("data :" + data.get(0));
       }
}

类型通配符下限通过形如 List<? super Number>来定义,表示类型只能接受Number及其三层父类类型,如 Object 类型的实例。

四,常见问题
1,不能使用基本数据类型实例化类型参数
2,运行时类型查询只适用于原始类型
3,泛型不能用在异常类实例
4,不能实例化类型变量
5,不能在静态内容中使用类型变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值