
这是原有的泛型接口和具体的某一个实现类
//泛型接口 public interface SaveService<T> { void save(List<T> saveList); } //具体实现类 public class UserSaveServiceIpl implements SaveService<User>{ @Override public void save(List<User> saveList) { //... } } 处于一些原因,必须把泛型接口改成非泛型接口...(很奇葩的问题,但是必须改掉接口的泛型)
public interface SaveService { <T> void save(List<T> saveList); } 于是想把泛型方法续上...强行续...
public class UserSaveServiceImpl implements SaveService{ @Override public <T> void save(List<T> saveList) { } //期望还能续上指定的类型 User } 结果也很明显,具体实现类上的类型算是完蛋啦,请问如何能满足这样的奇葩需要么(能满足么...
1 donggexiongdi 2021 年 12 月 30 日 看下 hashmap |
2 RiceMarch OP @donggexiongdi Map 也是泛型接口来着...public class HashMap<K,V> extends AbstractMap<K,V>,我就是不想加类的泛型 |
3 Jooooooooo 2021 年 12 月 31 日 没看懂... 而且你可以再想想是否提了 A/B 问题 |
4 Macolor21 2021 年 12 月 31 日 via iPhone 续上类型是什么意思? 你写的代码里写了一个泛型方法,那这个方法就是泛型的,它的约束范围只在方法级别。 你的问题描述不清楚,但有两种走向: 1. 你想实现类级别泛型,所有方法的返回类型等都是 User (只能泛型类 /接口) 2. 你想实现 save 的泛型。(你已经写出了泛型方法,但你没指定泛型类型,在实现类还是 T ,需要将 T 改成 User ,就可以了) 所以我还是不懂你的问题,你写的第二个实现中没有指定泛型类型,你的方法还是泛型方法。 在你的第一个实现中你指定了泛型 User 。该类继承 T 的方法都是泛型。 如果你是想用户使用 UserImpl 时,只能用 User 类型,那你把 T 改成 User 不就可以了? 方法调用层只能看到 List<User>的入参 |
5 wellsc 2021 年 12 月 31 日 via iPhone @Jooooooooo x y? |
6 RedrumSherlock 2021 年 12 月 31 日 via Android |
7 hingbong 2021 年 12 月 31 日 via Android 你是想接口方法是带泛型的,实现类不是?不行的,你想想你的需求在 |
8 hingbong 2021 年 12 月 31 日 via Android 你是想接口方法是带泛型的,实现类不是?不行的,结合多态来看,你想想你的需求在使用接口调用的时候怎么确定类型,除非在实现类判断类型,传参不对就报错 |
9 zhilincom 2021 年 12 月 31 日 不让用泛型是公司不让用吗?要么遵守要么跳槽。如果不是干嘛给自己找不自在? |
10 Ariver 2021 年 12 月 31 日 之前的实现,user 是被范型接口确定的,你的类,实现了这个,那么类型也就确定了。所以,方法上的,类型,也是确定的。 你想的实现,接口不是范型的,那么实现类上也就没有那个 T 的类型了。 那么,范型方法上的类型,就是在方法调用的时候根据传入的类型来决定的。 ps.一般来说,这种范型方法我们通常做法是<? extends T>. 这样在你的 save 方法内,才可以使用 T 这个父类上的方法,不然没啥用。 |
11 yidinghe 2021 年 12 月 31 日 via Android 接口改成这样,那就写一个唯一的实现类算了 |
12 kujio 2021 年 12 月 31 日 可以试试不用泛型,用一个被继承的实体抽象类来代替泛型 T |
13 RiceMarch OP @zhilincom 不是 是我另外的同事要在一个 list 塞这个接口的不同实现类 导致一个 list 有多种实现类,静态扫描被拒绝 所以他要求我把接口的泛型抹掉 哎 无奈 |
14 cppc 2021 年 12 月 31 日 @RiceMarch 这难道不是你同事的问题,List<SaveService<?>> 不行?如果不用泛型,那么是不是会有 SaveUserService,SaveXxxService ,这样 List 就能装下你得接口了? |
15 timethinker 2021 年 12 月 31 日 根据里氏替换原则,子类实例指向父类指针,也就是说假如有一个 SubUser extends User ,此时 List<User>是可以 add 这个 SubUser 实例的吧。如果想要返回 List<SubUser>,可以把方法签名改为 List<? extends User>。 |
16 timethinker 2021 年 12 月 31 日 @qwe520liao 这里说反了,应该是父类指针既可以指向父类实例,也可以指向子类实例。虽然 Java 没有指针的概念,但是这里相当于引用。 |
17 wolfie 2021 年 12 月 31 日 X Y +1 |
18 aguesuka 2021 年 12 月 31 日 @RiceMarch XY 问题, 你只需将 //泛型接口 public interface SaveService<T> { void save(List<T> saveList); } 改成 //泛型接口 public interface SaveService<T> { void save(List<? extends T> saveList); } |
19 aguesuka 2021 年 12 月 31 日 甚至是新的 method public interface SaveService<T> { void save(List<? extends T> saveList); void <T> saveAllWithoutTyping(List<T> saveList); } |
20 goalidea 2021 年 12 月 31 日 如果你确定该实现类型是 User 强转过来就行了 |
21 Joker123456789 2021 年 12 月 31 日 按照你现在的写法,你传进来什么类型,T 就是什么类型,但是无法 在创建对象的时候 约束 这个方法只能接收什么类型。 既然如此,不如 把 T 去掉咯,只要是 List 就收。 如果 你想 实现在创建对象的时候 约束 这个方法只能接收什么类型,那么 接口上的 <T> 是必须保留的,也就是必须用你一开始的那种方式。 如果你现在遇到的需求,用泛型是 最佳的方案,那你可以去跟 不让你用泛型的那个人 商量一下 怎么解决。 如果不用泛型问题也不大,那么干脆去掉泛型把,因为你现在的这个做法 体现不出泛型的意义。 |
22 aliveyang 2021 年 12 月 31 日 看不懂问题 |
23 RiceMarch OP @aguesuka 其实本质上是同事的奇葩想法 想把 interface SaveService<T>的这个 T 去掉我今天已经拒绝了他这个要求 hhhh |
24 RiceMarch OP @Joker123456789 确实是的 今天已经和她商量过了 List 的类型肯定还是要的 不然静态检查直接被拦截了 hhhhh 还是按照第一种继续做了 |
25 okou19900722 2022 年 1 月 7 日 很简单,因为 java 里的泛型是擦除的。 目前我了解的可以通过反射获取到泛型的,似乎只有子类实现父类时,传给父类的泛型可以获取,比如 List<String> list = new ArrayList<String>(); 这样写,拿不到,因为泛型是 ArrayList 上的,但 List<String> list = new ArrayList<String>(){}; 这样写就可以拿到泛型,这是因为这实际上是生成了一个 ArrayList 子类的匿名类的对象。 具体的原因,我说不清楚,写过 gson 的,应该对 TypeToken 很熟悉,基本都是 new TypeToken<xxxx>(){}的写法 |