generic in Java

The syntax for introducing a generic is to declare a formal type parameter in angle brackets. For example, the following class named Crate has a generic type variable declared after the name of the class:
```
public class Crate<T> {   
    private T contents;   
    public T emptyCrate() {      
        return contents;   
        
    }   
    public void packCrate(T contents) {      
        this.contents = contents;   
        
    }
}
```
Don’t worry if you can’t think of a use for generic classes of your own. Unless you are writing a library for others to reuse, generics hardly show up in the class definitions you write. They do show up frequently in the code you call, such as the Java Collections Framework.
```
Elephant elephant = new Elephant();
Crate<Elephant> crateForElephant = new Crate<>();
crateForElephant.packCrate(elephant);
Elephant inNewHome = crateForElephant.emptyCrate();
```
Just like a class, an interface can declare a formal type parameter. For example, the following Shippable interface uses a generic type as the argument to its ship() method:
```
public interface Shippable<T> {   
    void ship(T t);
}

```
It is also possible to declare them on the method level. This is often useful for static methods since they aren’t part of an instance that can declare the type. However, it is also allowed on non-static methods as well.In this example, the method uses a generic parameter:
```
public static <T> Crate<T> ship(T t) {
    System.out.println("Preparing " + t);   
    return new Crate<T>();
}
```
A generic class' type parameters cannot be sued in static contexts. Specifically, they cannot be the types of static fields, the types of parameters of static methods, or as the return types of static methods. In fact, this constraint make sense because static members are shared by all instances of the class. If type parameters were allowed there, when the class is instantiated with different type arguments, the compiler couldn't be able to identify the acturall types of those static fields, as well as static methods' parameters and return value.