泛型的本质:类型参数化。
一:泛型的优点:
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>的子类/子接口/实现类 在继承父类/继承父接口i/实现接口中
写法最好是 public class/interface 子类/子接口名字 extends/implements 父类/父接口名字<User>
或者 public class/interface 子类/子接口名字<E extends BasicTreeEntity> extends/implements 父类/父接口名字<E>
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
//另外一种解释 http://blog.csdn.net/hippoppower/article/details/4473991
c,方法参数 和 返回值类型 理解这种代码的写法 以后自己写代码多用这种.
定义父类型 传参的时候可以传递父类和父类的子类进去。返回实际类型。
调用上面的方法的代码
2,super
a,定义类 没有这种写法
b,定义变量 不理解这里 也不理解这种定义的用处。
List<Fruit> fruitList2 = new ArrayList<Fruit>();
或者
相关推荐
Dephi泛型generic的应用 .mht
C# 泛型(Generic) 泛型(Generic) 允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。换句话说,泛型允许您编写一个可以与任何数据类型一起工作的类或方法。 您可以通过数据...
陈广的泛型(Generic)教程
泛型在编程中是一种强大的工具,特别是在C#和.NET框架中,它允许程序员创建可复用的类型安全的代码,可以处理多种数据类型。在上述示例中,我们看到两个不同的场景,一个是非泛型的堆栈实现,另一个是使用.NET框架中...
11.4java-泛型(Generic)
"泛型演算法Generic Algorithms與Function Objects"这个主题深入探讨了这一关键领域。 首先,让我们了解什么是泛型算法。泛型算法是一组不依赖于特定数据类型的操作,它们能在任何满足特定接口要求的对象上工作。...
例如,我们可以创建一个名为`GenericContainer<T>`的泛型类,其中`T`就是类型参数。这个类可以存储任何类型的对象,但具体类型在实例化时确定。这样做的好处是,我们无需为每种可能的数据类型创建单独的类,从而提高...
泛型擦除(Generic erase)(教学视频+源代码) 源代码中使用的泛型,在经过编辑后,代码中就看不到泛型,也就是所谓的泛型擦除 泛型擦除不是泛型丢失了,而是在编译后的字节码文件中使用单独的标识来存储泛型了。...
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是...
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 SE 5.0 引入的新特性,它允许在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。然而,在 Java 中创建泛型数组却...
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是...
C# 泛型(Generic)详解 C# 中的泛型(Generic)是一种增强程序功能的技术,主要用于延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。泛型允许您编写一个可以与任何数据类型一起工作...
早在JDK1.3时,随着GJ(Generic Java)的出现,Java社区开始探索泛型的可能性。GJ是一个支持泛型特性的Java编译器插件,为后续的泛型技术发展奠定了基础。到了JDK1.4,通过JSR#14的支持,泛型技术以插件的形式得到了...
在C++/CLI中声明泛型类或方法时,使用`generic <typename T>`关键字,其中`T`是类型参数。例如,可以创建一个泛型栈`Stack`,如下所示: ```cpp generic ref class Stack { public: void Push(ItemType item) {…}...
Generic Programming(泛型程序设计小手册)中文chm版
在这个示例中,`GenericClass`被声明为泛型类,其中`T`是类型参数。创建`GenericClass`的实例时,我们指定了`String`作为类型实参,因此`set`和`get`方法都只能接受或返回`String`类型的值。 ### 泛型通配符 泛型...
数学和泛型编程-高效编程的奥秘(英文版pdf)原名:From_Mathematics_to_Generic_Programming,作者;Alexander A. Stepanov Daniel E. Rose