`

泛型 Generic

    博客分类:
  • j2se
 
阅读更多

 泛型的本质:类型参数化

一:泛型的优点:
    a, 让我们少写几个类的代码,b,让我们定义安全的泛型类

二:自定义泛型类:

package gen01;
/**
 * 自定义泛型类    BasicController
 * @author john
 *
 * @param <E>
 * @param <S>
 */
public class BasicController<E,S> {
	private E e;
	//private static S s; //泛型不能定义在静态属性上
	
	public BasicController() {
		super();	
	}
}

 

三:自定义泛型接口:

package gen01;
/**
 * 泛型接口  Comparator
 * @author john
 *
 * @param <E>
 */
public interface Comparator<E> {
	//接口不能有泛型属性,因为接口的属性是静态的。
	// /*public static final*/ E e;
	
	//公共的抽象方法
	/*public abstract */ E compare(E e);
}

 

四:自定义泛型方法:

package gen01;

import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * 非泛型类中定义泛型方法
 * @author john
 *
 */
public class Method {
	//自定义泛型方法   
	//定义:  在返回类型前加上<字母>
	public static <T> void test(T t){
		System.out.println(t);
	}
	
	//自定义释放资源的泛型方法
	public static <T extends Closeable> void testClose(T... t){
		for(T temp:t){
			try {
				if(null!=temp){
					temp.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) throws FileNotFoundException {
		test("自定义泛型方法测试");
		testClose(new FileInputStream("G:\\aaa.txt"));
	}
}

 

五:父类为泛型类,子类继承时:

    子类为富二代

package gen02;
/**
 * 泛型父类
 *1,保留父类泛型,子类必须为泛型。
 *2,不保留父类泛型,子类按需实现。
 *
 *属性及方法类型随位置而定
 *子类重写方法类型    --->随父类而定
 *eg: test 方法的参数
 *子类使用父类的属性  --->随父类而定
 *eg: this.age;
 *
 *子类中使用自己的属性 --->随自己而定
 *eg: Child1中的 A sex;
 *
 * @author john
 *
 * @param <T1>
 * @param <T2>
 */
public abstract class Father<T1,T2>{
	T1 age;
	public abstract void test(T2 name);
}

//保留
//1,全部保留
class Child1<T1,T2,A> extends Father<T1,T2>{
	A sex;
	
	@Override
	public void test(T2 name) {
		T1 t1 = this.age; //---> T1
	}
}

//2,部分保留
class Child2<T2,A> extends Father<Integer,T2>{

	@Override
	public void test(T2 name) {
		Integer tempAge = this.age; //--->Integer
	}}

//不保留
//1,有具体类型
class Child3 extends Father<Integer,String>{
	@Override
	public void test(String name) {
		Integer tempAge = this.age; //--->Integer
	}
}

//2,没有具体类型 ,擦除
class Child4 extends Father{

	@Override
	public void test(Object name) {
		Object tempAge = this.age; //--->Object
	}
}

//Child4 等价于  class Child5 extends Father<Object,Object>{}

六:接口为泛型接口 实现类实现时:

同上 

 

七:泛型擦除:

泛型擦除指使用|实现|继承的时候没有指定类型,我们称之为泛型擦除。

类似于Object, 不完全等同于Object   不指定类型编译不会自动检查,指定类型后编译会自动检查

package gen02;
/**
 * 泛型擦除
 * 泛型擦除指使用|实现|继承的时候没有指定类型
 * 类似于Object, 不完全等同于Object  不指定类型编译不会自动检查,指定类型后编译会自动检查
 * 
 * @author john
 */
public class MyStuApp {

	public static void main(String[] args) {
		MyStudent myStudent = new MyStudent<>();
		myStudent.setAge(18);
		Object age = myStudent.getAge();
		
		test(myStudent);//不指定类型编译不会自动检查
		
		MyStudent<Object> myStudent2 = new MyStudent<Object>();
		//test(myStudent2);//指定类型后编译会自动检查,此处会报错
	}
	
	public static void test(MyStudent<String> student){
		System.out.println(student.getAge());
	}
}

class MyStudent<T>{
	T age;
	public T getAge() {
		return age;
	}
	public void setAge(T age) {
		this.age = age;
	}
}

 八:泛型通配符"?":

表示类型不确定,只能用在声明变量,不能用在定义泛型类、泛型接口、泛型方法上。

 

package gen03;

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

public class WildcardTest {

	public static void main(String[] args) {
		//声明
		List<?> lists = new ArrayList<String>();	
		lists = new ArrayList<Integer>();
		lists = new ArrayList<Object>();
		
		//编译错误  通配符不能用来创建对象
		//lists = new ArrayList<?>();
	}
	
	public static void test(List<?> lists){
		
	}
	
	//不能用在创建泛型方法   编译通不过
//	public static <?> void test2(List<?> lists){
//		
//	}
}

//不能用在创建泛型类   编译通不过
//class Test<?>{
//	
//}

 

 

九:泛型上限"extends":

一般用于限制操作,表示小于等于,即子类或自身。

不能添加数据进去的理由是:保证向下兼容一致性。

 

package gen03;
/**
 * 继承链
 *      Object
 *        |
 *      Fruit
 *      /  \
 *   Apple Pear
 *     |
 *   FujiApple
 *   
 * @author john
 *
 */
public class Fruit {}

class Apple extends Fruit{};

class Pear extends Fruit{};

class FujiApple extends Apple{};

 

package gen03;

import java.util.ArrayList;
import java.util.List;
/**
 * extends 泛型上限  <=  即子类
 * 1,一般使用于限制操作。
 * 2,不能使用在添加数据操作     保证向下兼容一致性。
 * 3,规则
 * 
 * @author john
 */
public class ExtendsTest {

	public static void main(String[] args) {
		//extends 为上限
		//1 泛型定义属性
		Test<Fruit> test1 = new Test<Fruit>();
		Test<Pear> test2 = new Test<Pear>();
		Test<Apple> test3 = new Test<Apple>();
		
		//泛型没有多态     下面这行代码编译无法通过
//		Test<Apple> test4 = new Test<FujiApple>();
		
		List<? extends Fruit> list1 = new ArrayList<Fruit>();
		test(list1);
		
		List<Fruit> list2 = new ArrayList<Fruit>();
		test(list2);
		
		List<Apple> list3 = new ArrayList<Apple>();
		test(list3);
		
		List<? extends Apple> list4 = new ArrayList<FujiApple>();
		test(list4);
		
		//?  -->为什么报错  因为? 等同于 ? extends Object  Object>Fruit 所以报错
		List<?> list5 = new ArrayList<FujiApple>();
		//test(list5);
		
	}
	
	//2 使用extends定义泛型方法    ? extends Fruit
	public static void test(List<? extends Fruit> lists){
		//lists 不能添加任何非空对象 进去的理由是:保证向下兼容一致性。
//		lists.add(new Fruit());
//		lists.add(new Apple());
//		lists.add(new Pear());
//		lists.add(new FujiApple());
//		lists.add(null);
	}
	
	//泛型类
	static class Test<T extends Fruit>{}
}

 

十:泛型下限"super":

 一般用于限制操作,表示大于等于,即父类或自身。

不用用来添加父类数据进去的理由是:保证向上兼容一致性。

 

package gen03;
/**
 * 继承链
 *      Object
 *        |
 *      Fruit
 *      /  \
 *   Apple Pear
 *     |
 *   FujiApple
 *   
 * @author john
 *
 */
public class Fruit {}

class Apple extends Fruit{};

class Pear extends Fruit{};

class FujiApple extends Apple{};

 

package gen03;

import java.util.ArrayList;
import java.util.List;
/**
 * extends 泛型下限  >=   即父类或自身。
 * @author john
 */
public class SuperTest {

	public static void main(String[] args) {
		List<Fruit> list1 = new ArrayList<Fruit>();
		test(list1);
		
		List<Object> list2 = new ArrayList<Object>();
		test(list2);
		
		List<Apple> list3 = new ArrayList<Apple>();
		test(list3);
		
		List<? extends Apple> list4 = new ArrayList<Apple>();
		//test(list4); //编译通不过
	}
	
	// 使用extends定义泛型方法
	public static void test(List<? super Apple> lists){
		//自能添加自身或者子对对象    不能添加父类对象     理由是:保证向上兼容一致性。
		lists.add(new Apple());
		lists.add(new FujiApple());
		//lists.add(new Fruit());//编译通不过
	}
}

 

十一:泛型嵌套:

package gen03;
/**
 * 泛型嵌套
 * @author john
 *
 */
public class GenericQianTao {
	public static void main(String[] args) {
		Student<Integer> student = new Student<Integer>();
		student.setScore(100);
		Class<Student<Integer>> bj = new Class<Student<Integer>>();
		bj.setStudent(student);
		
		Student<Integer> stu = bj.getStudent();
		System.out.println(stu.getScore());
	}
}

class Student<T>{
	T score;

	public T getScore() {
		return score;
	}

	public void setScore(T score) {
		this.score = score;
	}
}

class Class<T>{
	T student;

	public T getStudent() {
		return student;
	}

	public void setStudent(T student) {
		this.student = student;
	}
} 

 

JDK里面嵌套的典型应用是Map集合遍历时使用Entry时的场景。

 

 

泛型没有多态。

没有泛型数组。

jdk1.7对泛型的简化 List<String> lists = new ArrayList<>();

 

 

后面的有时间整理下  20160509。

 

二: 定义泛型:
    a,定义单个类型持有者  UserDao<User>  userDao = new UserDao<User>();
    b,定义多个类型持有者  UserDao<Long,User>  userDao = new UserDao<Long,User>();

三:限制泛型的可用类型(有界类型 extends  super):
 1, extends
    a,定义类/接口
    public class UserDao<T>{
        ...
    }
    与
    public class UserDao<T extends Object>{
        ...
    }
    是等价的。
    
    所以我们想用限制类型定义类的时候该写成   注意1:不能用将T换成?  程序会报错。可以定义多个类型持有者。

    public class UD<T extends Fruit>{
        .... 

    }

    注意2:public   class/interface  父类/父接口名字<T>  
      或者  public   class/interface  类/接口名字<E extends BasicEntity> 
     的子类/子接口/实现类  在继承父类/继承父接口i/实现接口中   
     写法最好是   public  class/interface  子
类/子接口名字   extends/implements  类/接口名字<User>   
                 或者  
public  class/interface  子类/子接口名字<E extends BasicTreeEntity>   extends/implements  类/接口名字<E>

 
    b,定义变量   这里不理解为什么会报错   既然报错这种定义会有什么用处呢?

 

List<? extends Fruit> list1 = new ArrayList<Fruit>();

List<? extends Fruit> list2 = new ArrayList<Apple>();

List<? extends Fruit> list3 = new ArrayList<Orange>();

//list1.add(new Fruit()); // 报错

//list2.add(new Apple()); // 报错

  //list3.add(new Orange()); // 报错

    //list2  list3
//其实编译器根据 ? extends Fruit 只知道:list中可以是Fruit或它的任何某种子类型对象,但具体是什么类型是不确定的,
//所以你add(new Fruit()); add(new Orange()); add(new Apple()); 编译器都是会报错的;
//
//如果难理解,反过来理解:
//比如fruits.add(new Orange()),这里是add一个Orange类型对象,
//而fruits要求add的对象类型必须是Fruit或它的任何某种子类型对象,
//这个某种类型能用Orange或Fruit或Apple来表示吗?    

//另外一种解释   http://blog.csdn.net/hippoppower/article/details/4473991


    c,方法参数  和  返回值类型   理解这种代码的写法   以后自己写代码多用这种.  
    定义父类型   传参的时候可以传递父类和父类的子类进去。返回实际类型。

public static List<? extends Fruit> sortTreeList(List<? extends Fruit> list){
return list;
}
        
调用上面的方法的代码
List<Fruit> fruitList = new ArrayList<Fruit>();
fruitList.add(new Apple());
fruitList.add(new Orange());
sortTreeList(fruitList);
 或者
List<Apple> appleList = new ArrayList<Apple>();
appleList.add(new Apple());
sortTreeList(appleList);
 
 
  2,super
    a,定义类   没有这种写法

    b,定义变量       不理解这里      也不理解这种定义的用处。
List<? super Fruit> list4 = new ArrayList<Fruit>();
//List<? super Fruit> list5 = new ArrayList<Apple>();  // 报错
//List<? super Fruit> list6 = new ArrayList<Orange>(); // 报错
list4.add(new Apple());
list4.add(new Orange());
list4.add(new Fruit()); 
 
    c,定义方法和返回参数   理解这种代码的写法   但是不知道这种写法有什么适用场景。
    
public static List<? super Apple> sortTreeList2(List<? super Apple> list){
return list;
}
        调用上面的方法的代码
  List<Fruit> fruitList2 = new ArrayList<Fruit>();
fruitList2.add(new Apple());
fruitList2.add(new Orange());
sortTreeList2(fruitList);
        或者 
List<Apple> appleList2 = new ArrayList<Apple>();
appleList2.add(new Apple());
sortTreeList2(appleList);       



    
 

 

 

分享到:
评论

相关推荐

    Dephi泛型generic的应用 .mht

    Dephi泛型generic的应用 .mht

    C# 泛型(Generic)

    C# 泛型(Generic) 泛型(Generic) 允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。换句话说,泛型允许您编写一个可以与任何数据类型一起工作的类或方法。 您可以通过数据...

    泛型(Generic)

    陈广的泛型(Generic)教程

    泛型(generic)

    泛型在编程中是一种强大的工具,特别是在C#和.NET框架中,它允许程序员创建可复用的类型安全的代码,可以处理多种数据类型。在上述示例中,我们看到两个不同的场景,一个是非泛型的堆栈实现,另一个是使用.NET框架中...

    11.4java-泛型(Generic).md

    11.4java-泛型(Generic)

    泛型演算法Generic Algorithms與Function Objects

    "泛型演算法Generic Algorithms與Function Objects"这个主题深入探讨了这一关键领域。 首先,让我们了解什么是泛型算法。泛型算法是一组不依赖于特定数据类型的操作,它们能在任何满足特定接口要求的对象上工作。...

    C#泛型类、泛型方法、泛型接口、泛型委托的实例

    例如,我们可以创建一个名为`GenericContainer&lt;T&gt;`的泛型类,其中`T`就是类型参数。这个类可以存储任何类型的对象,但具体类型在实例化时确定。这样做的好处是,我们无需为每种可能的数据类型创建单独的类,从而提高...

    泛型擦除(Generic erase)(教学视频+源代码)

    泛型擦除(Generic erase)(教学视频+源代码) 源代码中使用的泛型,在经过编辑后,代码中就看不到泛型,也就是所谓的泛型擦除 泛型擦除不是泛型丢失了,而是在编译后的字节码文件中使用单独的标识来存储泛型了。...

    Generic_2(泛型类-泛型方法-泛型接口-泛型限定(上限)

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是...

    C#泛型概念的简介与泛型的使用

    namespace _1_3_1泛型Generic { class DyArray { private T[] arr; //泛型数组 public int Lenght; //数组大小 //构造函数 public DyArray(int size) { this.Lenght = size; arr = new T[size]; } //向...

    java泛型数组

    ### Java 泛型数组的理解与应用 #### 一、引言 Java 泛型是 Java SE 5.0 引入的新特性,它允许在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。然而,在 Java 中创建泛型数组却...

    Generic_3(泛型限定(下限)-泛型限定(上限的体现)-泛型限定(下限的体现)-泛型限定(通配符的体现)-集合查阅的技巧)

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是...

    实例讲解C# 泛型(Generic)

    C# 泛型(Generic)详解 C# 中的泛型(Generic)是一种增强程序功能的技术,主要用于延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。泛型允许您编写一个可以与任何数据类型一起工作...

    Jdk15泛型的实现

    早在JDK1.3时,随着GJ(Generic Java)的出现,Java社区开始探索泛型的可能性。GJ是一个支持泛型特性的Java编译器插件,为后续的泛型技术发展奠定了基础。到了JDK1.4,通过JSR#14的支持,泛型技术以插件的形式得到了...

    VC++ 2005:泛型编程

    在C++/CLI中声明泛型类或方法时,使用`generic &lt;typename T&gt;`关键字,其中`T`是类型参数。例如,可以创建一个泛型栈`Stack`,如下所示: ```cpp generic ref class Stack { public: void Push(ItemType item) {…}...

    Generic Programming(泛型程序设计小手册)

    Generic Programming(泛型程序设计小手册)中文chm版

    关于java的泛型.doc

    在这个示例中,`GenericClass`被声明为泛型类,其中`T`是类型参数。创建`GenericClass`的实例时,我们指定了`String`作为类型实参,因此`set`和`get`方法都只能接受或返回`String`类型的值。 ### 泛型通配符 泛型...

    数学和泛型编程-高效编程的奥秘(英文版pdf)原名:From_Mathematics_to_Generic_Programming

    数学和泛型编程-高效编程的奥秘(英文版pdf)原名:From_Mathematics_to_Generic_Programming,作者;Alexander A. Stepanov Daniel E. Rose

Global site tag (gtag.js) - Google Analytics