全面解析: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中的泛型,必须熟悉上面集中常用的。
}