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