您的位置:首页 > 编程语言 > Java开发

java 基础 泛型使用总结

2016-02-18 23:09 585 查看
没事,写一个关于泛型使用的总结,泛型相信大家都不陌生,学过javase的人都知道,泛型一般在框架中用的比较多,平时还是用的比较少的,今天就 总结下泛型怎么使用,

为什么jdk1.5要引入泛型?

先看段代码:

package com.generic;

import java.util.ArrayList;

import java.util.Iterator;

public class Demo1 {

public static void main(String[] args) {

ArrayList arrayList = new ArrayList();

arrayList.add("刘德华");

arrayList.add("王祖贤");

arrayList.add(100);

Iterator iterator = arrayList.iterator();

while(iterator.hasNext()){

String result = (String) iterator.next();//这里会报错

System.out.println(result);

}

}

}

比如上面的集合 我没有使用泛型,如果要遍历的话 我还要强转,而且我一不小心往集合中放了一个Integer类型进去,就容易报错,也许你会说 怎么可能自己会注意的,但是你做项目,而且忙起来那记得这么多,而且报错还是在运行期间报错,

更是致命,我们最好让错误发生在编译时间,这样程序员就可以修复这个错误,

所以总结起来引入泛型好处就是:减少了强转,增加了程序员的安全性,也方便了很多

那么泛型一般可以作用于:类,方法,接口上

泛型作用于类上就叫泛型类:先讲讲泛型类的使用

泛型类的使用

语法格式:public class 类名<泛型类型1,…> 注意:泛型类型必须是引用类型

写个demo玩下,

package com.generic;

public class Demo1 {

public static void main(String[] args) {

Person person = new Person("张三");

person.show();

Person person1 = new Person(1111);

person1.show();

}

}

class Person<T>{

private T mt;

public Person(T t) {

super();

this.mt = t;

}

public void show(){

System.out.println(mt);

}

}

只有在你创建对象时才知道泛型是什么类型的,这个特别适合在你抽取某一个功能时,需要父类引入泛型,子类具体传递那个泛型,android中adapter有几个方法 其实用到的也就是getView()方法,其他方法都用不上,而且每次都写在那里,那么这个时候你就写一个抽象的父类,把三个用不上的方法给写上 把getView()写成抽象的方法 因为每个子类实现不一样,这样你数据实体就可以使用泛型来定义,

泛型使用在类上有二个情况,一种是你知道传递什么类型,还有一个情况是你不知道传递什么类型,

知道传递什么类型的情况:

package com.generic;

public class Demo1 {

public static void main(String[] args) {

}

}

abstract class Person<T>{

}

class Man extends Person<String>{

}

在Man这个类中你知道要传递是String类型,如果你Man也不知道传递是什么泛型,可以这么写:

package com.generic;

public class Demo1 {

public static void main(String[] args) {

Man<String> man = new Man<String>();

man.show();

}

}

abstract class Person<T>{

}

class Man<T> extends Person<T>{

public void show(){

System.out.println("您好");

}

}

现在讲下泛型接口的时候:

语法格式:格式:public interface 接口名<泛型类型1…>

package com.generic;

public class Demo1 {

public static void main(String[] args) {

}

}

interface InnerImpl<T>{

public void show();

}

class A implements InnerImpl<String>{

@Override

public void show() {

}

}

泛型类和接口是一样的,在这不多讲,

泛型方法

把泛型定义在方法上

语法格式 : public <泛型类型> 返回类型 方法名(泛型类型 .)泛型接口

package com.generic;

public class Demo1 {

public static void main(String[] args) {

A a = new A();

a.show(0);

a.show("helloworld");

a.show(100);

}

}

class A{

public void show(String str){

System.out.println(str);

}

public void show(int i){

System.out.println(i);

}

public void show(double d){

System.out.println(d);

}

}

比如我在A类中 有这么多show的重载方法,如果我要让show方法接受的形参能根据它传递过来的就打印出来什么,我们就不用写那么多重载的方法了,这个就用泛型方法就可以解决!

package com.generic;

public class Demo1 {

public static void main(String[] args) {

A a = new A();

a.show(0);

a.show("helloworld");

a.show(100);

}

}

class A{

public <T >void show(T t){

System.out.println(t);

}

}

用泛型方法解决上面的 问题,我们知道方法有静态方法,那么静态方法有泛型会怎么办呢?

package com.generic;

public class Demo1 {

public static void main(String[] args) {

A a = new A();

a.show(0);

a.show("helloworld");

a.show(100);

}

}

class A{

public static <T >void show(T t){

System.out.println(t);

}

}

其实是一样的,但是有警告,它会让你直接用A的方式调用这个方法,而不是创建对象去调用方法,那么如果我方法有返回值呢?而且是泛型传递什么我就返回什么.

package com.generic;

public class Demo1 {

public static void main(String[] args) {

String str = A.show("helloword");

int i = A.show(100);

}

}

class A{

public static <T > T show(T t){

return t;

}

}

这样就ok,

泛型还有一个高级的地方就是泛型通配符

泛型通配符<?>

任意类型,如果没有明确,那么就是Object以及任意的Java类了

还是用例子来说明:

package com.generic;

import java.util.ArrayList;

import java.util.List;

public class Demo1 {

public static void main(String[] args) {

List<Object> obj = new ArrayList<Object>();

//下面三个报错是因为泛型如果明确写的时候,前后必须一致

// List<Object> obj1 = new ArrayList<Animal>();

// List<Object> obj2 = new ArrayList<Dog>();

// List<Object> obj3 = new ArrayList<Cat>();

//使用通配符

List<?> obj1 = new ArrayList<Animal>();

List<?> obj2 = new ArrayList<Dog>();

List<?> obj3 = new ArrayList<Cat>();

}

}

class Animal{

}

class Dog extends Animal{

}

class Cat extends Animal{

}

下面使用通配符就可以搞定了,

如果我现在有一个需求就是要求集合能存储的是Animal以及Animal的子类,这个时候就会用到? extends E 这个通配符了,它表示的是向下限定,E及其子类,如果不是E的子类放到集合中就会编译报错:

List<? extends Animal> obj1 = new ArrayList<Animal>();

List<? extends Animal> obj2 = new ArrayList<Dog>();

List<? extends Animal> obj3 = new ArrayList<Cat>();

现在需求又变了,我要求是传递Animal以及Animal的父类,就使用这个? super E E代表Animal,这个就不写demo玩了,好了 可以睡觉了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: