泛型在用法上可以分成泛型类和泛型方法两种:
泛型类
泛型类在实例化时就要指明类型,不同的类型实例必须要重新new一次,不够灵活
泛型接口interface Request
* 1.接口中有方法,且引用了泛型T时,class SubRequest
* 父子都要有
* 2.接口中没有方法,以下三种定义都可以,第三种相当字面T改成了字面M
* class SubRequest
* class SubRequest implements Request、
* class SubRequest
* 3.子类新增泛型
* class SubRequest
泛型方法
定义泛型方法时,必须在返回值前加上
// 无返回值
public static
System.out.println(t.getClass());
}
// 有返回值
User user = test();
System.out.println(user);
public static
Object user = new User();
return (T) user;
}
泛型方法的真实案例,可以点击这里查看,基于CountDownLatch的单元测试并发工具类,此案例在实际工作中可以用到,另外我实现了一套泛型的内存队列,写这篇博客也是想总结一下用法,给迷茫的人一些启示。
Class、Class、Class>、Class< T>的应用
* 泛型类
* public interface Request
void serialize(T t);
}
* 声明对象方式:Request request、Request
* 声明对象方式:Request> request,调用serialize方法,任意类型的参数都不会编译成功
* 声明对象方式:Request
* 泛型方法
*
* }
*
* return (V) null;
* }
* 方法参数V相当于Object,可以是任意类型
List
List
List
? extends E和? super E什么时候用
泛型结构只参与“读”操作则限定上界(extends关键字),例如下面idea生成的for循环代码,直接使用Integer表示
public static void read1(List extends Integer> list) {
for (Integer integer : list) {
}
}
泛型结构只参与“写”操作则限定下界(super关键字),例如下面idea生成的for循环代码,直接使用Object表示
public static void read(List super Integer> list) {
for (Object o : list) {
}
}
泛型方法的应用
public final class MapControl {
private MapControl() {
}
/**
* 单例
*/
private static final MapControl mapControl;
/**
* 数据,实际应用中可以把这个当成RedisTemplate
* Map
*/
private static final Map map;
/**
* 控制并发20
*/
private static final Semaphore semaphore;
static {
mapControl = new MapControl();
map = new ConcurrentHashMap<>();
semaphore = new Semaphore(20);
}
private static
try {
semaphore.acquire();
return map;
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
public static void release() {
semaphore.release();
}
private static Object execute(Statement statement) {
try {
Map map = MapControl.getMap();
return statement.prepare(map);
} finally {
release();
}
}
interface Statement
/**
* 方法返回Object更具有统一性,因为不确定返回数据的的类型,例如方法返回V,返回List
* 所以返回Object可以兼容一切返回类型,再强转为需要的类型
*
* @param map
* @return
*/
Object prepare(final Map
}
public static
MapControl.execute(new MapControl.Statement
@Override
public V prepare(Map
map.put(key, value);
return null;
}
});
}
public static
/**
* 返回时强转为V
*/
return (V) MapControl.execute(new Statement
@Override
public V prepare(Map
return map.get(key);
}
});
}
public static
/**
* 返回时强转为Map
*/
Map
@Override
public Object prepare(Map
Map
for (K k : keys) {
result.put(k, map.get(k));
}
return result;
}
});
return result;
}
public static void main(String[] args) {
MapControl.set(1, "1");
MapControl.set("name", "p7+");
Object obj = new Object();
MapControl.set(obj, obj);
MapControl.set(2, 2);
MapControl.set(3, 3);
MapControl.set(4, 4);
MapControl.set("name1", "name1");
MapControl.set("name2", "name2");
String v = MapControl.get(1);
System.out.println(v);
System.out.println(MapControl.get("1"));
System.out.println(MapControl.get("name"));
System.out.println(MapControl.get(obj));
List
keys.add(2);
keys.add(3);
keys.add(4);
System.out.println(MapControl.getAll(keys));
List
strKeys.add("name");
strKeys.add("name1");
strKeys.add("name2");
System.out.println(MapControl.getAll(strKeys));
}
}