黑马程序员-Generic
来源:互联网 发布:白酒网络推广方案 编辑:程序博客网 时间:2024/04/29 06:17
---------------------android培训、java培训、期待与您交流! -------------------------
Generic Types:
A generic type is a generic class or interface that is parameterized over types.
通过示例代码,对Java中的Generic有个直观的认识:
//普通的Generic Typeclass Box<T> {private T t;public void set(T t) {this.t = t;}public T get() {return this.t;}}//Bounded Type Parametersclass NaturalNumber<T extends Number> {private T n;public NaturalNumber(T n) {this.n = n;}public boolean isEven() {return n.intValue() % 2 == 0;}}//Multiple Type Parametersinterface Pair<K, V> {void setKey(K k);void setValue(V v);K getKey();V getValue();}class OrderedPair<K, V> implements Pair<K, V> {private K key;private V value;public OrderedPair() {}public OrderedPair(K key, V value) {this.key = key;this.value = value;}@Overridepublic void setKey(K k) {this.key = k;}@Overridepublic void setValue(V v) {this.value = v;}@Overridepublic K getKey() {return this.key;}@Overridepublic V getValue() {return this.value;}}class Util {//Generic Methodpublic static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {return p1.getKey().equals(p2.getKey()) &&p2.getValue().equals(p2.getValue());}//generic Methods and Bounded Type Parameterspublic static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) {int count = 0;for (T e : anArray) {if (e.compareTo(elem) > 0) {count++;}}return count;}}public class UCTest {@Testpublic void test1() {//A type variable can be any non-primitive type you specify://any class type, any interface type, any array type, or even//another type variable.Box<Integer> box = new Box<>();box.set(Integer.valueOf(3));//由于存在auto boxing 机制, 也可以采用如下的调用方式box.set(5);Integer i = box.get();//从此句代码看出,Generic后类型的好处,提供类型信息,减少代码出错System.out.println(i);}@Testpublic void test2() {//The diamond , complier infer since 1.7Pair<Integer, String> p1 = new OrderedPair<>(1, "apple");Pair<Integer, String> p2 = new OrderedPair<Integer, String>(2, "pear");System.out.println("IsSame: " + Util.compare(p1, p2));Box<String> box = new Box<>();Pair<Integer, Box<String>> p3 = new OrderedPair<>(3, box);box.set("p3");System.out.format("%s:%s%n", p3.getKey(), p3.getValue().get());}@Testpublic void test3() {/* * A raw type is the name of generic class or interface without any type arguments. * However, a non-generic class or interface type is not raw type */Box<String> stringBox = new Box<>();Box rawBox = stringBox;//rawBox.set(3);//System.out.println(rawBox.get());Box<Integer> intBox = rawBox;//warning: unchecked conversion}}
Generics, Inheritance, and Subtypes
public void boxTest(Box<number> n) { /*...*/ }//上面的函数只接受 Box<number></number>
interface PayLoadList<E, P> extends List<E> { /*...*/}
Type Inference
class BoxDemo {public static <U> void addBox(U u, List<Box<U> list) {Box<u> box = new Box<>();box.set(u);list.add(box);}public static <U> void outputBoxes(List<Box<U>> list) {int counter = 0;for (Box<U> box : list) {U boxContents = box.get();System.out.println("Box #" + counter + "contains [" +boxContents + "]");counter++;}}}@Testpublic void test4() {//The type Inference of Generic class, since 1.7List<Box<Integer>> list = new ArrayList<>();BoxDemo.<Integer>addBox(Integer.valueOf(3), list);//The Type Inference of Generic MethodBoxDemo.addBox(4, list);BoxDemo.addBox(5, list);BoxDemo.outputBoxes(list);}//Target Typesvoid processStringList(List<String> stringList) {}processStringList(Collections.<string>emptyList());</string>
Wildcards
//Upper Bounded Wildcardspublic static double sumOfList(List<? extends Number> list) { double s = 0.0; for (Number n : list) s += n.doubleValue(); return s;}//Unbounded Wildcardspublic static void printList(List<?> list) { for (Object elem: list) System.out.print(elem + " "); System.out.println();}//Lower Bounded Wildcardspublic static void addNumbers(List<? super Integer> list) { for (int i = 1; i <= 10; i++) { list.add(i); }}
Type Erasure
public class Node<T> { private T data; private Node<T> next; public Node(T data, Node<t> next) } this.data = data; this.next = next; } public T getData() { return data; } // ...}//Erasure of Generic Typespublic class Node { private Object data; private Node next; public Node(Object data, Node next) { this.data = data; this.next = next; } public Object getData() { return data; } // ...}//bounded type parameterpublic class Node<T> extends Comparable<T> { private T data; private Node<T> next; public Node(T data, Node<t> next) { this.data = data; this.next = next; } public T getData() { return data; } // ...}//The Java compiler replaces the bounded type parameter T with the first bound class, Comparable:public class Node { private Comparable data; private Node next; public Node(Comparable data, Node next) { this.data = data; this.next = next; } public Comparable getData() { return data; } // ...}//erasure of generic methodspublic static <T> int count(T[] anArray, T elem)public static int count(Object[] anArray, Object elem)//Suppose the following classes are defined:class Shape { /* ... */ }class Circle extends Shape { /* ... */ }class Rectangle extends Shape { /* ... */ }//You can write a generic method to draw different shapes:public static <T extends Shape> void draw(T shape) { /* ... */ }//The Java compiler replaces T with Shape:public static void draw(Shape shape) { /* ... */ }//bridge methodsclass MyNode extends Node<Integer> { //bridge method generated by the compiler public void setData(Object data) { setData((Integer)data); }}</t>
总结
//由于存在ErasureBox<String> box = new Box<>();Box<Integer> box1 = new Box<>();System.out.Println(box.getClass() == box1.getClass())//output: true
//Generic type的类型决断只在编译时起作用//可以通过reflect修改Generic type的值, 不受参数类型约束//类型限制只存在编译前,如果通过反射绕过编译器,则可以设置其他类型的值//Type parameter 要用Object.class替代,实际字节流中就是ObjectBox<Integer> box = new Box<>();Class<?> c = box.getClass();Method m = c.getMethod("set", new Class<?>[] {Object.class});m.invoke(box, "haha");System.out.println(box.get());//output: haha//获取类型参数TypeVariable[] tv = c.getTypeParameters();
//获取Generic Methods 相关信息public class GenericTest { public static void main(String[] args) throws Exception { Method method = GenericTest. class.getMethod("applyVector" , Vector.class); Type[] types = method.getGenericParameterTypes(); ParameterizedType pType = (ParameterizedType)types[0]; System.out.println(pType.getRawType()); //结果:class java.util.Vector System. out.println(pType.getActualTypeArguments()[0]); //结果:class java.util.Date } public static void applyVector(Vector≶Date> v1){ }}
//不可以用原始数据类型实例化Generic TypeBox<int> box = new Box<>(); //非法
//不可以创建类型参数的实例 public static <E> void append(List<E> list) { E e = new E(); //compile-time error}
//static修饰的成员的类型与类的类型参数相同class<T> Myclass { public static <T> test() {} //complie-time error public static T os;}
//不可以 Cast or instanceof with parameterized typespublic static void rtti(List<?> list) { if (list instanceof ArrayList<Integer>) { //compile-time error }}List<integer> li = new ArrayList<>();List<number> ln = (List<number>)li; //compile-time error</number></number></integer>
//Cnnot create arrays of parameterized typesT[] arr = new T[0]; //compile-time error
//Cannot create, catch, or throw objects of parameterized type//you canclass Parser<T extends Exception> { public void parse() throws T { }}
//Cannot Overload a Method Where the Formal Parameter Types of Each Overload Erase to the Same Raw Typepublic class Example { public void print(Set<string> strSet) { } public void print(Set<integer> intSet) { }}//The overloads would all share the same classfile representation and will generate a compile-time error.</integer></string>
---------------------android培训、java培训、期待与您交流! -------------------------
0 0
- 黑马程序员-泛型Generic
- 黑马程序员-Generic
- 黑马程序员:Generic泛型
- 黑马程序员_Java_泛型(Generic)
- 黑马程序员_泛型(Generic)
- 黑马程序员----泛型(Generic)
- 黑马程序员_泛型(Generic)
- 黑马程序员—高新技术:泛型Generic
- 黑马程序员——泛型(Generic)
- 黑马程序员——【Java】【高新技术】泛型 Generic
- 黑马程序员-->Java基础加强-->泛型(Generic)
- 黑马程序员Java学习笔记之泛型Generic
- 黑马程序员_高新技术三(JavaBean复杂操作,注解Annotation,泛型应用Generic)
- 黑马程序员_高新技术3(JavaBean复杂操作,注解Annotation,泛型应用Generic)
- 黑马程序员面试题高新技术之(JavaBean复杂操作,注解Annotation,泛型应用Generic)
- 黑马程序员——泛型(Generic)的理解和使用
- 黑马程序员——泛型(Generic)的理解和使用
- Generic
- 线程同步-生产者与消费者问题
- 支持向量机笔记(二) Lagrange duality拉格朗日对偶
- class-dump逆向分析app
- Pills - HDU 4165 递推打表
- 关于hibernate锁,缓存
- 黑马程序员-Generic
- tar命令【自己留存】
- 用户空间和内核空间通讯之【proc文件系统】
- Windows Live Writer测试帖
- 那么为什么作为函数形参的数组和指针申明可以互换呢?
- VIPS:基于视觉的Web页面分页算法
- K-means聚类算法
- Handler有何作用?如何使用?
- select超时