ZhengJiayin 1 month ago
parent
commit
5195010aa9
  1. 97
      w8/Cache.java
  2. 70
      w8/Java泛型学习笔记.txt
  3. 37
      w8/Pair.java

97
w8/Cache.java

@ -0,0 +1,97 @@
import java.util.HashMap;
import java.util.Map;
public class Cache<K, V> {
private Map<K, CacheEntry> cacheMap;
public Cache() {
cacheMap = new HashMap<>();
}
public void put(K key, V value) {
cacheMap.put(key, new CacheEntry(value));
}
public void put(K key, V value, long expireTimeMs) {
cacheMap.put(key, new CacheEntry(value, expireTimeMs));
}
public V get(K key) {
CacheEntry entry = cacheMap.get(key);
if (entry == null) {
return null;
}
if (entry.isExpired()) {
cacheMap.remove(key);
return null;
}
entry.updateAccessTime();
return entry.getValue();
}
public boolean containsKey(K key) {
CacheEntry entry = cacheMap.get(key);
if (entry == null) {
return false;
}
if (entry.isExpired()) {
cacheMap.remove(key);
return false;
}
return true;
}
public V remove(K key) {
CacheEntry entry = cacheMap.remove(key);
return entry != null ? entry.getValue() : null;
}
public int size() {
return cacheMap.size();
}
public void clear() {
cacheMap.clear();
}
private class CacheEntry {
private V value;
private long createTime;
private long accessTime;
private long expireTimeMs;
public CacheEntry(V value) {
this(value, -1);
}
public CacheEntry(V value, long expireTimeMs) {
this.value = value;
this.expireTimeMs = expireTimeMs;
this.createTime = System.currentTimeMillis();
this.accessTime = this.createTime;
}
public V getValue() {
return value;
}
public void updateAccessTime() {
this.accessTime = System.currentTimeMillis();
}
public boolean isExpired() {
if (expireTimeMs <= 0) {
return false;
}
return System.currentTimeMillis() > createTime + expireTimeMs;
}
public long getCreateTime() {
return createTime;
}
public long getAccessTime() {
return accessTime;
}
}
}

70
w8/Java泛型学习笔记.txt

@ -0,0 +1,70 @@
AI协同学习:Java泛型
1. 泛型擦除后如何通过反射获取泛型信息?
Java泛型擦除后,泛型类型信息会被擦除为它们的边界或Object。但在某些情况下(如继承泛型类或实现泛型接口),可以通过反射获取泛型信息的Type。
关键API:
- Class.getGenericSuperclass() - 获取带泛型的父类
- Method.getGenericReturnType() - 获取方法返回值的泛型类型
- ParameterizedType.getActualTypeArguments() - 获取泛型参数的实际类型
示例代码:
```java
import java.lang.reflect.*;
import java.util.*;
// 方法1:通过子类获取泛型父类的Type
class StringList extends ArrayList<String> {}
Type parentType = StringList.class.getGenericSuperclass();
// parentType = java.util.ArrayList<java.lang.String>
if (parentType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) parentType;
Type[] typeArgs = pt.getActualTypeArguments();
for (Type typeArg : typeArgs) {
System.out.println("Type arg: " + typeArg); // java.lang.String
}
}
// 方法2:通过方法返回值获取泛型信息
Method method = GenericReflection.class.getMethod("getCache");
Type returnType = method.getGenericReturnType();
if (returnType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) returnType;
System.out.println("Return type args: " + Arrays.toString(pt.getActualTypeArguments()));
}
```
2. Cache 代码审查
Cache 实现分析:
优点:
- 使用了合理的缓存数据结构
- 实现了过期机制
- 包含 containsKey、remove、clear 等完整API
- 内部类 CacheEntry 封装良好
问题和建议:
1. 线程不安全 - 如果多线程并发访问会有问题,建议添加同步或使用 ConcurrentHashMap
2. 泛型信息丢失 - CacheEntry 中保存了 V value,但由于类型擦除,无法在运行时获取 V 的具体类型
3. remove 方法在并发场景下可能有空指针问题
思考题:为什么Java泛型不支持基本类型?
核心原因:历史兼容性和类型系统设计
1. 类型擦除机制 - Java泛型在运行时会被擦除为 Object。基本类型(如 int、long)不是对象,不能赋值给 Object,所以无法进行类型擦除。
编译后变成:
ArrayList<int> → ArrayList<Object> // int不是Object
ArrayList<Integer> → ArrayList<Object> // Integer是Object
2. 自动装箱的性能开销 - 虽然有 int ↔ Integer 自动装箱,但这会带来额外的性能开销。Java设计者选择不让泛型支持基本类型,以保持性能。
3. 向后兼容性 - Java 1.5 才引入泛型,为了兼容旧代码(没有泛型时 ArrayList 可以存任何对象),选择用类型擦除实现。
简单记忆:Java泛型本质是"伪泛型",它只在编译期提供类型检查,运行时没有泛型信息。基本类型不是对象,无法参与类型擦除。

37
w8/Pair.java

@ -0,0 +1,37 @@
public class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public Pair<V, K> swap() {
return new Pair<>(value, key);
}
@Override
public String toString() {
return "Pair{" +
"key=" + key +
", value=" + value +
'}';
}
}
Loading…
Cancel
Save