首页 > 其他分享 >KTV和泛型(2)

KTV和泛型(2)

时间:2022-10-09 09:59:43浏览次数:62  
标签:KTV System println 泛型 new public out

很多使用泛型的小伙伴,都会有一个疑惑:为什么有的方法返回值前带<T>、<K, V>之类的标记,而有的方法返回值前又什么都不带呢?就像这样:

// 实体基类
class Entity {
   public String toString() {
      return "Entity";
   }
}
// 用户类
class User extends Entity {
   public String toString() {
      return "User";
   }
}
// 用户Dao
class UserDao {
   public String toString() {
      return "UserDao";
   }
}

 

/**
 * 带<E>标记与不带<E>标记的比较
 */
public class GenericsClass<T extends Entity> {
   // 不带标记
   public void notSign(T t) {
      System.out.println("notSign  " + t.toString());
   }

   // 带<T>标记
   public <T> void hasSign(T e) {
      System.out.println("hasSign  " + e.toString());
   }

   public static void main(String[] args) {
      GenericsClass<Entity> clazz = new GenericsClass<>();
      Entity entity = new Entity();
      User user = new User();
      UserDao userDao = new UserDao();

      System.out.println("不带标记的方法:");
      clazz.notSign(entity);
      clazz.notSign(user);
      // 不能编译通过的
      // 因为在GenericsClass<T extends Entity>中已经限定了全局的T为Entity及其子类,
      // 所以不能再加入UserDao;
      // clazz.notSign(userDao);

      System.out.println("带标记的方法:");
      clazz.hasSign(entity);
      clazz.hasSign(user);
      // 带上前缀<E>,就是在告诉编译器:这是新指定的一个类型,代表该方法自己独有的某个类,
      // 跟GenericsClass<T extends Entity>中的Entity及其子类没有任何关系
      // 或者说
      // hasSign方法重新定义泛型T、隐藏或者代替了GenericsClass<T>中的T,不再受限于Entity及其子类
      clazz.hasSign(userDao);
   }
}

 

因此,返回值前面的<T>的作用是「重新定义泛型」,因此方法参数类型不受对象泛型类型的限制。在Java新的Stream API中有大量这种带前缀的用法,例如:

ArrayList.java:public <T> T[] toArray(T[] a)

Optional.java:public static <T> Optional<T> of(T value)

Collectors.java:public static <T> Collector<T, ?, List<T>> toList()

 

泛型,作为Java的一个基础特性,并不是一点毛病都没有,「泛型擦除」就是至今还未解决的一个问题(这个问题其实对于大多数人来说可以不用知道,因为实际应用中极少出现这种场景,感兴趣的话稍稍了解一下,不喜可绕过)。

所谓泛型擦除,是这样一个问题:

class User {}
class Product {}
class Shop<V> {}
class Particle<PPP, QQQ> {}

public class LostInformation<T> {
   public static void main(String[] args) {
      // ArrayList<String>和ArrayList<Integer>应该是不同的类型,但结果是它们完全相等
      Class<?> c1 = new ArrayList<String>().getClass();
      Class<?> c2 = new ArrayList<Integer>().getClass();
      System.out.println(c1 == c2);

      // 无法从泛型获得任何有关参数类型的信息
      List<User> list = new ArrayList<>();
      Map<User, Product> map = new HashMap<>();
      Shop<User> shop = new Shop<>();
      Particle<Long, Double> p = new Particle<>();
      System.out.println(Arrays.toString(list.getClass().getTypeParameters()));
      System.out.println(Arrays.toString(map.getClass().getTypeParameters()));
      System.out.println(Arrays.toString(shop.getClass().getTypeParameters()));
      System.out.println(Arrays.toString(p.getClass().getTypeParameters()));
   }
}

 

可以看见,Particle<Long, Double>中关于Long和Double的信息已经完全丢失了,只剩下了最初的PPP和QQQ,真的应了那句话:历经千帆,归来仍是是少年!

但这是编程啊,不是文案啊~,不能这样丢掉了!

 

标签:KTV,System,println,泛型,new,public,out
From: https://www.cnblogs.com/xiangwang1111/p/16770391.html

相关文章

  • C#委托之一例看懂泛型委托
    以为委托在编程中频繁使用,所以微软为使开发者方便使用委托,省去繁琐的重复定义。给我们提供了三种定义好的泛型委托,分别是Action、Func和Predicate。下面分别介绍Action:......
  • Java 一个List泛型根据另一个List泛型的属性进行过滤
    这个需求是在批量入库的时候,进行批量校验用到的1.逻辑是传入List参数,需要入库2.根据List去查询库中是否存在3.用传入的List进行过滤,获取苦衷不存在的resList4.插入resLi......
  • 【Java基础】泛型概述、泛型方法、泛型接口、类型通配符及可变参数的使用
    目录​​一、泛型概述和好处​​​​二、泛型类​​​​三、泛型方法​​​​四、泛型接口​​​​五、类型通配符​​​​六、可变参数​​​​可变参数的使用​​一、泛型......
  • net中c#教程 list泛型的常用操作
    上一篇讲的是非常基础的string字符串操作,这在c#的应用非常广泛。今天深入一点,讲下List泛型的一些用法。对于泛型的增删改查操作,找本c#的基础教程书籍,看看就行了。   ......
  • 算法 玩转数据结构 2-6 使用泛型
    0课程地址https://coding.imooc.com/lesson/207.html#mid=13411 1重点关注1.1泛型改造==转equals详见3  2课程内容见3 3......
  • C#委托总结 普通委托、泛型委托、匿名委托
     一、概念委托的本质也是一种类型,类似于Class这样。作用是将一个方法作为参数传递给另一个方法,关键字是delegate 二、委托的定义使用步骤第一步声明委托:publicdel......
  • Java泛型
    Java泛型本文源自https://www.yuque.com/qingkongxiaguang/javase/syy4rz#29e0f372欢迎大家去看b站这个Up主的Java视频https://www.bilibili.com/video/BV1Gv411T7pi?p=......
  • C++ 泛型(模板与容器)
    文章目录​​一、泛型的基本思想:​​​​函数模板的性质​​​​C++模版函数/类的语法​​​​类模板的性质​​​​二、C++STL简介​​​​2.1算法(algorithm)​​​​2.......
  • go 泛型
            ......
  • Java泛型总结
     为什么会有泛型?泛型是用来干什么的?泛型其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛......