From 5195010aa97abe2601925ef946b8464fa272a77f Mon Sep 17 00:00:00 2001 From: ZhengJiayin <13230092115@163.com> Date: Wed, 13 May 2026 21:05:46 +0800 Subject: [PATCH] w8 --- w8/Cache.java | 97 +++++++++++++++++++++++++++++++++++ w8/Java泛型学习笔记.txt | 70 +++++++++++++++++++++++++ w8/Pair.java | 37 +++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 w8/Cache.java create mode 100644 w8/Java泛型学习笔记.txt create mode 100644 w8/Pair.java diff --git a/w8/Cache.java b/w8/Cache.java new file mode 100644 index 0000000..9a2fe62 --- /dev/null +++ b/w8/Cache.java @@ -0,0 +1,97 @@ +import java.util.HashMap; +import java.util.Map; + +public class Cache { + private Map 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; + } + } +} \ No newline at end of file diff --git a/w8/Java泛型学习笔记.txt b/w8/Java泛型学习笔记.txt new file mode 100644 index 0000000..3bf1ace --- /dev/null +++ b/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 {} +Type parentType = StringList.class.getGenericSuperclass(); +// parentType = java.util.ArrayList + +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 → ArrayList // int不是Object +ArrayList → ArrayList // Integer是Object + +2. 自动装箱的性能开销 - 虽然有 int ↔ Integer 自动装箱,但这会带来额外的性能开销。Java设计者选择不让泛型支持基本类型,以保持性能。 + +3. 向后兼容性 - Java 1.5 才引入泛型,为了兼容旧代码(没有泛型时 ArrayList 可以存任何对象),选择用类型擦除实现。 + +简单记忆:Java泛型本质是"伪泛型",它只在编译期提供类型检查,运行时没有泛型信息。基本类型不是对象,无法参与类型擦除。 \ No newline at end of file diff --git a/w8/Pair.java b/w8/Pair.java new file mode 100644 index 0000000..404b350 --- /dev/null +++ b/w8/Pair.java @@ -0,0 +1,37 @@ +public class Pair { + 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 swap() { + return new Pair<>(value, key); + } + + @Override + public String toString() { + return "Pair{" + + "key=" + key + + ", value=" + value + + '}'; + } +} \ No newline at end of file