Java专题

全面解析:java中的泛型使用,内含代码验证解析

2020-11-02  本文已影响0人  千夜零一

介绍

  泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
  泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类泛型接口泛型方法


泛型类

第一步:创建泛型类

/**
 * @data on 2020/11/2 11:56 AM
 * @auther armStrong
 * @describe 泛型类
 */
public class Generic <T>{

    private T key;

    public Generic(T key) {
        this.key = key;
    }

    public T getKey(){
        return key;
    }
}

第二步:在Activity中调用

第一种:传入实参

private void useT1() {
    //Generic<T> g = new Generic<T>(xxx);
    //在传入实参的时候需要传入相应的类型
    Generic<Integer> genericInteger = new Generic<Integer>(123456);
    Generic<String> genericString = new Generic<String>("key_vlaue");
    Log.d("泛型测试","key is " + genericInteger.getKey());
    Log.d("泛型测试","key is " + genericString.getKey());
    //输出结果:D/泛型测试: key is 123456
    //输出结果:D/泛型测试: key is key_vlaue
}

第二种:不传入实参

private void useT2() {
    //不用传实参,自动匹配
    Generic generic = new Generic("111111");
    Generic generic1 = new Generic(4444);
    Generic generic2 = new Generic(55.55);
    Generic generic3 = new Generic(false);

    Log.d("泛型测试","key is " + generic.getKey());
    Log.d("泛型测试","key is " + generic1.getKey());
    Log.d("泛型测试","key is " + generic2.getKey());
    Log.d("泛型测试","key is " + generic3.getKey());
    //输出结果:D/泛型测试: key is 111111
    //输出结果:D/泛型测试: key is 4444
    //输出结果:D/泛型测试: key is 55.55
    //输出结果:D/泛型测试: key is false
}

泛型接口类

第一步:创建泛型接口类

/**
 * @data on 2020/11/2 12:09 PM
 * @auther armStrong
 * @describe 泛型接口
 */
public interface TestGeneric<T> {
    public T next();
}

第二步:创建泛型接口实现类

/**
 * @data on 2020/11/2 12:12 PM
 * @auther  armStrong
 * @describe 泛型接口-实现类(当实现泛型接口的类,传入泛型实参时)
 */
public class TestGenericImpl implements TestGeneric<String> {

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

    @Override
    public String next() {
        Random rand = new Random();
        return fruits[rand.nextInt(3)];
    }
}

第三步:在Activity中调用

//泛型接口
private void useInterfaceT() {
    TestGenericImpl tgi = new TestGenericImpl();
    Log.d("泛型测试","key is "+tgi.next());
    //输出结果:D/泛型测试: key is Apple
}

泛型通配符

定义方法:

public void showKeyValue1(Generic<?> obj){
    Log.d("泛型测试","key value is " + obj.getKey());
}

调用方法:

private void useT3(){
        Generic<Integer> gInteger = new Generic<Integer>(123);
        Generic<Number> gNumber = new Generic<Number>(456);
        showKeyValue1(gNumber);
        showKeyValue1(gInteger);
        //输出结果:D/泛型测试: key value is 456
        //输出结果:D/泛型测试: key value is 123
    }

完整Activity代码

public class Case44 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_case44);
//        error(); //基础测试:类型不相符会报错
//        compare(); //类型比较
//        useT1(); //使用泛型(传入实参)
//        useT2(); //使用泛型(不传实参)
//        useInterfaceT();//使用泛型接口
        useT3();
    }
    //泛型类
    private void error() {
        List arrayList = new ArrayList();
        arrayList.add("aaaa");
        arrayList.add(100);

        for(int i = 0; i< arrayList.size();i++){
            String item = (String)arrayList.get(i);
            Log.d("泛型测试","item = " + item);
            //报错:java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        }
    }
    private void compare(){
        List<String> stringArrayList = new ArrayList<String>();
        List<Integer> integerArrayList = new ArrayList<Integer>();

        Class classStringArrayList = stringArrayList.getClass();
        Class classIntegerArrayList = integerArrayList.getClass();

        if(classStringArrayList.equals(classIntegerArrayList)){
            Log.d("泛型测试","类型相同");
            //输出结果:D/泛型测试: 类型相同
        }
    }

    private void useT1() {
        //Generic<T> g = new Generic<T>(xxx);
        //在传入实参的时候需要传入相应的类型
        Generic<Integer> genericInteger = new Generic<Integer>(123456);
        Generic<String> genericString = new Generic<String>("key_vlaue");
        Log.d("泛型测试","key is " + genericInteger.getKey());
        Log.d("泛型测试","key is " + genericString.getKey());
        //输出结果:D/泛型测试: key is 123456
        //输出结果:D/泛型测试: key is key_vlaue
    }

    private void useT2() {
        //不用传实参,自动匹配
        Generic generic = new Generic("111111");
        Generic generic1 = new Generic(4444);
        Generic generic2 = new Generic(55.55);
        Generic generic3 = new Generic(false);

        Log.d("泛型测试","key is " + generic.getKey());
        Log.d("泛型测试","key is " + generic1.getKey());
        Log.d("泛型测试","key is " + generic2.getKey());
        Log.d("泛型测试","key is " + generic3.getKey());
        //输出结果:D/泛型测试: key is 111111
        //输出结果:D/泛型测试: key is 4444
        //输出结果:D/泛型测试: key is 55.55
        //输出结果:D/泛型测试: key is false
    }

    //泛型接口
    private void useInterfaceT() {
        TestGenericImpl tgi = new TestGenericImpl();
        Log.d("泛型测试","key is "+tgi.next());
        //输出结果:D/泛型测试: key is Apple
    }

    //泛型通配符
    public void showKeyValue(Generic<Number> obj){
        Log.d("泛型测试","key value is " + obj.getKey());
    }
    public void showKeyValue1(Generic<?> obj){
        Log.d("泛型测试","key value is " + obj.getKey());
    }

    private void useT3(){
        Generic<Integer> gInteger = new Generic<Integer>(123);
        Generic<Number> gNumber = new Generic<Number>(456);
//        showKeyValue(gNumber);  //这句没问题
        // showKeyValue(gInteger);  //这句话编译中报错
        // showKeyValue这个方法编译器会为我们报错:Generic<java.lang.Integer>
        // cannot be applied to Generic<java.lang.Number>

        //应该使用泛型通配符?如下写法,使用showKeyValue1方法。
        showKeyValue1(gNumber);
        showKeyValue1(gInteger);
        //输出结果:D/泛型测试: key value is 456
        //输出结果:D/泛型测试: key value is 123
    }
    //说明:范型方法相对上面几种更为复杂,也不太常用,以后用到再进行解析用法。
    //了解java中的泛型,必须熟悉上面集中常用的。
}

大功告成!

上一篇下一篇

猜你喜欢

热点阅读