java泛型详细介绍,以及为何泛型类不能写相同占位符的静态泛型方法

java泛型,以及为何泛型类不能写相同占位符的静态泛型方法

1.首先为什么要有泛型
先来看一段代码

public class Demo1 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();//不指定泛型的时候我们发现他可以存放多种类型数据
        list.add("1");
        list.add(12);
        list.add('a');
        list.add(true);
        Object obj=list.get(0);//但是当为我们取得时候他返回的数据是Object 并不是我们想要的数据类型
        //给我取出来索引为0 的数据   是字符串的1
        //放进去的是STring类型的数据,结果直接取的是Object
         String str = (String)list.get(0);//我们要想得到我们存放的必须强制类型转换
        //Object是多有类的超类,范围大===》转为String类型数据
        //Object===>String精度有可能丢失。所以不符合咱们开发的需求。
        System.out.println(str);

		//当我们加了泛型以后,对存放的数据起到了约束的作用,只能存放我们想要的数据
		ArrayList<String> list1= new ArrayList<>();
        list1.add("花花");
        list1.add("小小");
        list1.add("帅帅");

        String s = list1.get(1);//我们在取值的时候会直接返回数据的原来类型
		
}

由此可见在编程中我们规范数据类型一致化就很有必要了

2. 泛型的介绍
        泛型是Java 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
        在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患
    
3.泛型的好出
    泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。不仅约束了数据的类型,还使代码变得更加的普适性。

4.泛型的简单使用
    泛型可以作用在方法上,类上,接口上,分别被叫做泛型方法,泛型类,泛型接口,接下来我们就来简单介绍一下

泛型作用在方法上:
语法格式:权限修饰符 [static] <自定义无意义的占位符> 返回值类型[可以使用自定义的泛型] >方法名字(必须有一个带有自定义泛型的参数) {

//方法体

}

public class FanXing {
    public static void main(String[] args) {
        FanXing fanXing=new FanXing();
        //定义一个学生类
        Student stu=
                new Student("1001","花花",22,'男',"管理学");
        //此刻T代表任意数据类型,基本数据类型 或引用数据类型都可以
        // 此处以引用数据类型Student为例
        Student text = fanXing.text(stu);
        System.out.println(text);

		//调用静态泛型方法 此时
       Integer[] arr=new Integer[]{1,2,3,4,5};
       int[] arr1=new int[]{1,2,3,4,5};
       print(arr);//因为不识别基本数据类型,传入arr1会报错,只能识别引用数据类型

    }
    /**
     * 非静态的泛型例子
     * @param t 
     * @param <T>
     * @return
     */
    public <T> T text(T t){
        System.out.println(t);
        return t;
    }
    /**
     * 静态的泛型例子
     * @param arr
     * @param <T>
     */
    public static <T> void print(T[] arr){
        for (T t:arr) {
            System.out.println(t);
        }
    }
    
}

自定义泛型在类中如何使用

语法格式:class 类名<自定义泛型无意义的占位符> {
    非静态的变量和非静态成员方法【注意】 就可以来使用类的泛型了
}

/**
 * 带有自定义泛型的类
 * @param <T>
 */
public class Test1<T> {

    /**
     *使用了自定义的泛型
     * @param t 和类名一致的泛型
     * @return 和类名一致的自定义泛型
     */
    public T getType(T t) {
        return t;
    }

    /**
     *测试参数
     * @param t
     */
    public void testArgs(T t) {
        System.out.println(t);
    }

    /*为什么类内的静态方法不能使用和类名一致的自定义泛型。
    *因为:我们调用静态方法的时候是 类名.静态方法名 
    * 如果泛型静态方法借用了泛型类的占位符 T 此时我们还没有对类进行实例化也就没有给类泛型T类型 此时我们
    * 的静态方法还没有传入T为什么类型			    
    * 所以JVM虚拟机是无法识别静态方法上的方法参数类型的  所以是不被允许的
    */
    public static T testStatic(T t) {  //此方法系统系统会报错,不能借用类泛型的T
        System.out.println(t);
        return t;
    }
    /*
	 *但是如果我们就想要定义泛型静态方法呢
	 *这事我们可以换个占位符 与类上的T 区别开 这样我们就可以避开了因为
	 *他们两个代表的是不一样的数据类型
	 *
	 */
     public static <E>E testStatic(E t) {
        System.out.println(t);
        return t;
    }
}

泛型在接口中的使用
语法格式

interface 接口的名字 <自定义泛型无意义的占位符>
{
}

public interface A<T> {
    public void test(T t);
}

public class TestA<T> implements A<T>{
    @Override
    public void test(T t) {
        System.out.println(t);
    }

    public static void main(String[] args) {
        A<String> stringTestA = new TestA<>();
        A<Dog> dogTestA = new TestA<>();
        //t   =====>new Dog(1, "旺财")
        dogTestA.test(new Dog(1, "旺财"));
        stringTestA.test("asd");
    }
}

  • 2
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值