Java编程思想:泛型方法
import java.util.*; public class Test { public static void main(String[] args) { // GenericMethods.test(); // GenericVarargs.test(); BasicGeneratorDemo.test(); } } /* 如论合适,如果使用泛型方法可以取代将整个类泛型化,那么就应该只使用泛型方法 因为它可以使事情更清楚明白。另外,对于一个static的方法而言,无法访问泛型类 的类型参数,所以,如果static方法需要使用泛型的能力,就必须使其成为泛型方法 */ class GenericMethods { public <T> void f(T x) { System.out.println(x.getClass().getName()); } public static void test() { GenericMethods gm = new GenericMethods(); // gm.f(""); // gm.f(1); // gm.f(1.0); // gm.f('c'); // gm.f(gm); gm.f(New.map()); } } /* 需求: 利用方法的推导功能,简化我们创建集合类时的编码,但是这个工作 现在已经不需要了,因为IDE和编译器都可以满足自动推导的功能。 */ class New { public static <K,V> Map<K,V> map() { return new HashMap<>(); } } /* 类型推导只对赋值操作有效果,其他时候并不起作用。如果你将一个泛型方法 调用的结果(例如New.map())作为参数,传递给另一个方法时,这时候编译 器并不会执行类型推导。这种情况下,编译器认为:调用泛型方法后,其返回值 被赋给了一个Object类型的变量 ——现在好像可以哦 */ class LimtsOfInference { static void f(Map<String, List<? extends Map>> arg) { } static void test() { f(New.map()); } } /* 泛型方法中,显式指明类型的语法。要显式指明类型,必须在点操作符 与方法名之间插入尖括号,然后把类型置于尖括号内。 ——这些知识点,有点不适用了,现在 */ class LimtsOfInference2 { static void f(Map<String, List<? extends Map>> arg) { } static void test() { f(New.<String,List<? extends Map>>map()); } } /* 15.4.2 可变参数与泛型方法 */ class GenericVarargs { public static <T> List<T> makeList(T... args) { List<T> result = new ArrayList<>(); for (T item : args) { result.add(item); } return result; } static void test() { List<String> ls = makeList("A"); System.out.println(ls); ls = makeList("A", "B", "C"); System.out.println(ls); ls = makeList("adfasdfsafsdf".split("")); System.out.println(ls); } } /* 15.4.3 用于Generator的泛型方法 */ interface Generator<T>{ T next(); } class Generators { //给我一个容器,给我一个生成器,我帮你把容器填满,只省下了几行for循环的代码 public static <T> Collection<T> fill(Collection<T> coll, Generator<T> gen, int len) { ; i < len; i++) { coll.add(gen.next()); } return coll; } } /* 15.4.4 一个同游的Generator 下面的程序,可以为任何类构造一个Generator,只要该类具有默认的构造器,为了 减少类型的声明,它提供了一个泛型的方法,用于生成BasicGenerator。我感觉我 上一个小节的代码,也可以为任何类构造了一个Generator啊 我觉得真正的区别会在这儿,以往的Generator,是需要自己去实现next()部分的 代码的,而这个Generator却不用,你传给它一个Class对象,它就能为你生成许多 个对象,是真正意义上的简化了操作 */ class BasicGenerator<T> implements Generator<T> { private Class<T> type; public BasicGenerator(Class<T> type) { this.type = type; } @Override public T next() { try { return type.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } public static <T> Generator<T> create(Class<T> type) { return new BasicGenerator<>(type); } } class CounterObject { ; private final long id = counter++; public long id() { return id; } public String toString() { return "Counted Object "+id; } } class BasicGeneratorDemo { static void test() { Generator<CounterObject> g = BasicGenerator.create(CounterObject.class); ; i < ; i++) { System.out.println(g.next()); } } } /* 15.4.5 简化元组的使用 */ class TwoTuple<A, B> { public final A first; public final B second; public TwoTuple(A first, B second) { this.first = first; this.second = second; } public String toString() { return "(" + first + "," + second + ")"; } } /* 这个方案只是在创建的时候,给简化了一下,统一了一下创建的接口 */ class Tuple { public static <A, B> TwoTuple<A, B> tuple(A a, B b) { return new TwoTuple<>(a, b); } } /* 问题: 方法f()返回一个参数化的TwoTuple对象,而f2()返回的是非参数化的 TwoPuple对象。在这个例子中,编译器并没有f2()的警告信息,因为我们 并没有将其返回值作为参数化对象使用。在某种意义上,它被“向上转型”为 一个非参数化的TwoTuple。然而,如果试图将f2()的返回值转型为参数化 的TwoTuple,编译器就会发出警告 ——有点尴尬,参数化其实就是指的泛型化 */ class TupleTest { static TwoTuple<String, String> f() { return Tuple.tuple("AAA","BBB"); } static TwoTuple f2() { return Tuple.tuple("BBB","CCC"); } static void test(){} } /* 15.4.6 一个Set实用工具 需求: 用Set表示集合的各种关系,如交集、并集、、补集 */ class Sets { public static <T> Set<T> union(Set<T> a, Set<T> b) { Set<T> result = new HashSet<>(a); a.addAll(b); return result; } public static <T> Set<T> intersection(Set<T> a, Set<T> b) { Set<T> result = new HashSet<>(a); result.retainAll(b); return result; } public static <T> Set<T> difference(Set<T> superset, Set<T> subset){ Set<T> result = new HashSet<>(superset); result.retainAll(subset); return result; } public static <T> Set<T> complement(Set<T> a, Set<T> b) { return difference(union(a,b),intersection(a,b)); } } enum Letters{ A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z } /* EnumSet: 用来从enum直接创建Set,在这儿,我们向static方法EnumSet.range()传入某个范围的 第一个元素和最后一个元素,然后它将返回一个Set,其中包括该范围内的所有元素 */ class LettersDemo { static void test() { /* 我看案例中,有一个import static.generics.watercolors.Watercolos.* 又看到他解释说:为了方便起见(可以直接使用enum中的元素名),下面的实例以 static的方式引入Watercolors。 ——这种写法,我从来没有用过,标记一下 */ Set<Letters> l1 = EnumSet.range(Letters.A, Letters.D); //。。。 } }
Java编程思想:泛型方法的更多相关文章
- Java编程思想(11~17)
[注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第十一章 持有对象 11.1 泛型和类型安全的容器>eg: List<St ...
- 《Java编程思想》读书笔记
前言 这个月一直没更新,就是一直在读这本<Java编程思想>,这本书可以在Java业界被传神的一本书,无论谁谈起这本书都说好,不管这个人是否真的读过这本书,都说啊,这本书很好.然后再看这边 ...
- Java编程思想(后)
Java编程思想(后) 持有对象 如果一个程序只包含固定数量的且其生命期都是已知的对象,那么这是一个非常简单的程序. Java中的库基本类型: List, Set, Queue和Map --- 称为集 ...
- Java中的泛型 --- Java 编程思想
前言 我一直都认为泛型是程序语言设计中一个非常基础,重要的概念,Java 中的泛型到底是怎么样的,为什么会有泛型,泛型怎么发展出来的.通透理解泛型是学好基础里面中非常重要的.于是,我对<Ja ...
- JAVA编程思想——分析阅读
需要源码.JDK1.6 .编码风格参考阿里java规约 7/12开始 有点意识到自己喜欢理论大而泛的模糊知识的学习,而不喜欢实践和细节的打磨,是因为粗心浮躁导致的么? cron表达式使用 设计能力.领 ...
- Java编程思想 笔记
date: 2019-09-06 15:10:00 updated: 2019-09-24 08:30:00 Java编程思想 笔记 1. 四类访问权限修饰词 \ 类内部 本包 子类 其他包 publ ...
- 《Java编程思想》读书笔记(二)
三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第一章到第十章的内容,这一次记录的是第 ...
- JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)
switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) ...
- 《Java编程思想》学习笔记(二)——类加载及执行顺序
<Java编程思想>学习笔记(二)--类加载及执行顺序 (这是很久之前写的,保存在印象笔记上,今天写在博客上.) 今天看Java编程思想,看到这样一道代码 //: OrderOfIniti ...
- #Java编程思想笔记(一)——static
Java编程思想笔记(一)--static 看<Java编程思想>已经有一段时间了,一直以来都把笔记做在印象笔记上,今天开始写博客来记录. 第一篇笔记来写static关键字. static ...
随机推荐
- SqlServer 复制中将大事务分成小事务分发
原文:SqlServer 复制中将大事务分成小事务分发 在sql server 复制中,当在发布数据库执行1个大事务时,如一次性操作 十万或百万以上的数据.当操作数据在发布数据库执行完成后 ,日志读取 ...
- List.Sort() 小小技巧--- 从大到小排列
List.sort() 默认的情况下是从小到大的排列. 例如: List<int> list = new List<int>(); list.Add(- ...
- 微信小程序把玩(三十八)获取设备信息 API
原文:微信小程序把玩(三十八)获取设备信息 API 获取设备信息这里分为四种, 主要属性: 网络信息wx.getNetWorkType, 系统信息wx.getSystemInfo, 重力感应数据wx. ...
- RxJava入门优秀博客推荐
RxJava用了快半年了,现在越来越离不开这个库,从使用到逐渐接触它的背后实现,突然想写点什么关于RxJava的内容.在酝酿如何组织内容的时候,就去看看自己关于RxJava的收藏,发现满满的干货! 1 ...
- Android零基础入门第65节:RecyclerView分割线开发技巧
在上一期通过简单学习,已经领略到了RecyclerView的灵活性,当然都是一些最基础的用法,那么本期一起来学习RecyclerView的分割线使用. 相信有的比较细心的同学已经发现了,使用Recyc ...
- 自己总结OpenSSL的变化
经过查看openssl源码自带的Makefile,发现: 1) 从0.9.7开始 https://www.openssl.org/source/old/0.9.x/openssl-0.9.7k.tar ...
- xe5 for android 地理定位GPS
先上源码,在解释. implementation uses androidapi.jni.JavaTypes, androidapi.jni.Location, FMX.helpers.android ...
- Python正则表达式基础指南
1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十 ...
- ssh证书登录
前言 本文基于实际Linux管理工作,实例讲解工作中使用ssh证书登录的实际流程,讲解ssh证书登录的配置原理,基于配置原理,解决实际工作中,windows下使用SecureCRT证书登录的各种问题, ...
- Vue.js 是如何实现 MVVM 的?
目录 框架到底为我们做了什么? 如何理解 MVVM ? 如何实现 MVVM - 以 Vue.js 为例 Vue 如何实现响应式 Vue 如何解析模板 Vue.js 运行机制 手写一个 Vue.js 框 ...