Java Tutorial/Generics/Generics Basics

Материал из Java эксперт
Перейти к: навигация, поиск

A Generic Class with Two Type Parameters

class TwoGen<T, V> {
  T ob1;
  V ob2;
  TwoGen(T o1, V o2) {
    ob1 = o1;
    ob2 = o2;
  }
  void showTypes() {
    System.out.println("Type of T is " + ob1.getClass().getName());
    System.out.println("Type of V is " + ob2.getClass().getName());
  }
  T getob1() {
    return ob1;
  }
  V getob2() {
    return ob2;
  }
}
public class MainClass {
  public static void main(String args[]) {
    TwoGen<Integer, String> tgObj = new TwoGen<Integer, String>(88, "Generics");
    tgObj.showTypes();
    int v = tgObj.getob1();
    System.out.println("value: " + v);
    String str = tgObj.getob2();
    System.out.println("value: " + str);
  }
}



Type of T is java.lang.Integer
Type of V is java.lang.String
value: 88
value: Generics


A generic type can accept more than one type variables.

import java.util.HashMap;
import java.util.Map;
public class MainClass {
    public static void main (String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put ("key1", "value1");
        map.put ("key2", "value2");
        String value1 = map.get("key1");
    }
}





Generics Work Only with Objects

Gen<int> strOb = new Gen<int>(53); // Error, can"t use primitive type





Introducing Generic Types

  1. A generic type can accept parameters.
  2. A generic type is often called a parameterized type.
  3. You pass reference types in angle brackets to generic types.



List<E> myList;



E is called a type variable, namely a variable that will be replaced by a type.

  1. A generic type that uses a type variable E allows you to pass E when declaring or instantiating the generic type.
  2. If E is a class, you may also pass a subclass of E
  3. If E is an interface, you may also pass a class that implements E.
  4. By convention, you use a single uppercase letter for type variable names.


Life without Generics

When retrieving a member from stringList1, you get an instance of java.lang.Object. In order to work with the original type of the member element, you must first downcast it to String.



import java.util.ArrayList;
import java.util.List;
public class MainClass {
  public static void main(String[] args) {
    List stringList1 = new ArrayList ();
    stringList1.add ("Java 5");
    stringList1.add ("with generics");

    String s1 = (String) stringList1.get (0);
    
  }
}





Nested generic type

A generic type is itself a type and can be used as a type variable. For example, if you want your List to store lists of strings:



List<List<String>> myListOfListsOfStrings;





Raw Types and Legacy Code

To handle the transition to generics, Java allows a generic class to be used without any type arguments. This creates a raw type for the class.



// Demonstrate a raw type.
class Gen<T> { 
  T ob;
   
  Gen(T o) { 
    ob = o; 
  } 
 
  T getob() { 
    return ob; 
  } 
} 
 
public class MainClass { 
  public static void main(String args[]) { 
    Gen<Integer> iOb = new Gen<Integer>(88); 
    Gen<String> strOb = new Gen<String>("Generics Test"); 
 
    Gen raw = new Gen(new Double(98.6));
    // Cast here is necessary because type is unknown.
    double d = (Double) raw.getob();
    System.out.println("value: " + d);
    strOb = raw; // OK, but potentially wrong
    String str = strOb.getob();  
  
  // This assignment also overrides type safety.
  raw = iOb; // OK, but potentially wrong
  d = (Double) raw.getob(); 
    
  } 
}



Exception in thread "main" value: 98.6
java.lang.ClassCastException: java.lang.Double
  at MainClass.main(MainClass.java:26)


What Are Generics? A Simple Generics Example

The term generics means parameterized types. (Java 2 V5.0 (Tiger) New Features by Herbert Schildt )

  1. T is a type parameter that will be replaced by a real type.
  2. T is the name of a type parameter.
  3. This name is used as a placeholder for the actual type that will be passed to Gen when an object is created.



class GenericClass<T> {
  T ob;
  GenericClass(T o) {
    ob = o;
  }
  T getob() {
    return ob;
  }
  void showType() {
    System.out.println("Type of T is " + ob.getClass().getName());
  }
}
public class MainClass {
  public static void main(String args[]) {
    // Create a Gen reference for Integers.
    GenericClass<Integer> iOb = new GenericClass<Integer>(88);
    iOb.showType();
    // no cast is needed.
    int v = iOb.getob();
    System.out.println("value: " + v);
    // Create a Gen object for Strings.
    GenericClass<String> strOb = new GenericClass<String>("Generics Test");
    strOb.showType();
    String str = strOb.getob();
    System.out.println("value: " + str);
  }
}



Type of T is java.lang.Integer
value: 88
Type of T is java.lang.String
value: Generics Test


Working with generic List

import java.util.ArrayList;
import java.util.List;
public class MainClass {
  public static void main(String[] args) {
    List stringList1 = new ArrayList();
    stringList1.add("Java 5");
    stringList1.add("with generics");
    String s1 = (String) stringList1.get(0);
    System.out.println(s1.toUpperCase());

    List<String> stringList2 = new ArrayList<String>();
    stringList2.add("Java 5");
    stringList2.add("with generics");

    String s2 = stringList2.get(0);
    System.out.println(s2.toUpperCase());
  }
}