如何设计制作一个网站,网页升级访问紧急大通知狼,乔智云智能建站,给男票做网站表白的软件1. 前言
泛型编程自从 Java 5.0 中引入后已经超过15个年头了。对于现在的 Java 码农来说熟练使用泛型编程已经是家常便饭的事情了。所以本文就在不对泛型的基础使用在做说明了。 如果你还不会使用泛型的话#xff0c;可以参考下面两个链接
Java 泛型详解The Java™ Tutorial…1. 前言
泛型编程自从 Java 5.0 中引入后已经超过15个年头了。对于现在的 Java 码农来说熟练使用泛型编程已经是家常便饭的事情了。所以本文就在不对泛型的基础使用在做说明了。 如果你还不会使用泛型的话可以参考下面两个链接
Java 泛型详解The Java™ Tutorials (Lesson: Generics)
这篇文章就简答聊一下我实际在开发工作中很少用的到泛型方法这个知识点以及在实际项目中有哪些东西会使用到泛型。
2. 泛型方法
在阅读代码的时候我们经常会看到下面这样的方法 (这段代码摘自 java.util.AbstractCollection) public T T[] toArray(T[] a) {// Estimate size of array; be prepared to see more or fewer elementsint size size();T[] r a.length size ? a :(T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);IteratorE it iterator();for (int i 0; i r.length; i) {if (! it.hasNext()) { // fewer elements than expectedif (a r) {r[i] null; // null-terminate} else if (a.length i) {return Arrays.copyOf(r, i);} else {System.arraycopy(r, 0, a, 0, i);if (a.length i) {a[i] null;}}return a;}r[i] (T)it.next();}// more elements than expectedreturn it.hasNext() ? finishToArray(r, it) : r;
}那么 pulic 关键字后面的那个 T 就是用来标记这个方法是一个泛型方法。 那什么是泛型方法呢。
官方的解释是这样的
Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameters scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.通俗点来将就是将一个方法泛型化让一个普通的类的某一个方法具有泛型功能。 如果在一个泛型类中增加一个泛型方法那这个泛型方法就可以有一套独立于这个类的泛型类型。
通过一个简单的例子, 我们来看看
/*** GenericClass 这个泛型类是一个简单的套皮的 HashMap*/
public class GenericClassK, V {private MapK, V map new HashMap();public V put(K key, V value) {return map.put(key, value);}public V get(K key) {return map.get(key);}// 泛型方法 genericMethod 可以接受一个全新的、作用域只限本函数的泛型类型Tpublic T T genericMethod(T t) {return t;}}实际使用起来
GenericClassString, Integer map new GenericClass();
// put 和 get 方法的参数必须使用定义时指定的 String 和 Integer
System.out.println(map.put(One, 1));
System.out.println(map.get(One));
// 泛型方法 genericMethod 就可以接受一个 String 和 Integer 以外的类型
System.out.println(map.genericMethod(new Double(1.0)).getClass());我们再来看看 JDK 中使用到泛型方法的例子。我们最常使用的泛型容器 ArrayList 中有个 toArray 方法。JDK 在它的实现中就提供了两个版本其中一个就是泛型方法的版本
public class ArrayListE extends AbstractListEimplements ListE, RandomAccess, Cloneable, java.io.Serializable
{// 这是一个普通版本返回一个Object的数组public Object[] toArray() {return Arrays.copyOf(elementData, size);}// 这是一个泛型方法的版本将容器里存储的元素输出到 T[] 数组中。 其中 T 必须是 E 的父类否则 System.arraycopy 会抛出 ArrayStoreException 异常 public T T[] toArray(T[] a) {if (a.length size)// Make a new array of as runtime type, but my contents:return (T[]) Arrays.copyOf(elementData, size, a.getClass());System.arraycopy(elementData, 0, a, 0, size);if (a.length size)a[size] null;return a;}
}泛型方法总体上来说就是可以给与现有的方法实现上增加一个更加灵活的实现可能。
3. 实战应用
在实际的项目中对于泛型的使用除了像倾倒垃圾一样往泛型容易里塞各种 java bean 和其他泛型对象。还能怎么使用泛型呢
我们在实际的一些项目中会对数据库中的一些表(多数时候是全部)先实现 CRUD (Create, Read, Update, Delete)的操作并从这些操作中延伸出一些简单的 REST 风格的 WebAPI 接口然后才会根据实际业务需要实现一些更复杂的业务接口。
大体上会是下面这个样子。 // 这是一个简单的 Entity 对象
// 通常现在的 Java 应用都会使用到 Lombok 和 Spring Boot
Data
AllArgsConstructor
NoArgsConstructor
ToString
Entity
Table(name user)
public class User {Idprivate Long id;private String username;private String password;
}// 然后这个是 DAO 接口继承自 spring-data 的 JpaRepository
public interface UserDao extends JpaRepositoryUser, Long {
}// 在来是一个访问 User 资源的 Service 和他的实现
public interface UserService {ListUser findAll();OptionalUser findById(Long id);User save (User user)void deleteById(Long id);
}Service
public class UserSerivceImpl implements UserService {private UserDao userDao;public UserServiceImpl(UserDao userDao) {this.userDao userDao;}Overridepublic ListUser findAll() {return this.dao.findAll();}Overridepublic OptionalUser findById(Long id) {return this.dao.findById(id);}Overridepublic User save(User user) {return this.dao.save(user);}Overridepublic void deleteById(Long id) {this.dao.deleteById(id);}
}// 最后就是 WebAPI 的接口了
RestController
RequestMapping(/user/)
public class UserController{private UserService userService;public UserController(userService userService) {this.userService userService;}GetMappingResponseBodypublic ListUser fetch() {return this.userService.findAll();}GetMapping({id})ResponseBodypublic User get(PathVariable(id) Long id) {// 由于是示例这里就不考虑没有数据的情况了return this.userService.findById(id).get();}PostMappingResponseBodypublic User create(RequestBody User user) {return this.userService.save(user);}PutMapping({id})ResponseBodypublic User update(RequestBody User user) {return this.userService.save(user);}DeleteMapping({id})ResponseBodypublic User delete(PathVariable(id) Long id) {User user this.userService.findById(id);this.userService.deleteById(id);return user;}
}大致一个表的一套相关接口就是这个样子的。如果你的数据库中有大量表的话而且每个表都需要提供 REST 风格的 WebAPI 接口的话那么这将是一个相当枯燥的而又及其容易出错的工作。
为了不让这项枯燥而又容易犯错的工作占去我们宝贵的私人时间我们可以通过泛型和继承的技巧来重构从 Service 层到 Controller 的这段代码(感谢 spring-data 提供了 JpaRepository, 让我们不至于从 DAO 层重构)
3.1 Service 层的重构
首先是 Service 接口的重构我们 Service 层接口就是定义了一组 CRUD 的操作我们可以将这组 CRUD 操作抽象到一个父接口然后所有 Service 层的接口都将继承自这个父接口。而接口中出现的 Entity 和主键的类型(上例中 User 的主键 id 的类型是 Long)就可以用泛型来展现。
// 这里泛型表示 E 来指代 Entity, ID 用来指代 Entity 主键的类型
public interface ICrudServiceE, ID {ListE findAll();OptionalE findById(ID id);E save(E e);void deleteById(ID id);
}// 然后 Service 层的接口就可以简化成这样
public interface UserService extends ICrudServiceUser, Long {
}同样 Service 层的实现也可以使用相似的方法具体实现可以抽象到一个基类中。
// 相比 ICrudService 这里有多了一个泛型 T 来代表 Entity 对应的 DAO, 我们的每一个 DAO 都继承自
// spring-data 的 JpaRepository 所以这里可以使用到泛型的边界
public abstract class AbstractCrudServiceT extends JpaRepositoryE, ID, E, ID {private T dao;public AbstractCrudService(T dao) {this.dao dao;}public ListE findAll() {return this.dao.findAll();}public OptionalE findById(ID id) {return this.dao.findById(id);}public E save(E e) {return this.dao.save(e);}public void deleteById(ID id) {this.dao.deleteById(id);}
}// 那 Service 的实现类可以简化成这样
Service
public class UserServiceImpl extends AbstractCrudServiceUserDao, User, Long implements UserService {public UserServiceImpl(UserDao dao) {supper(dao);}
}同样我们可以通过相同的方法来对 Controller 层进行重构
// Controller 层的基类
public abstract class AbstractCrudControllerT extends ICrudServiceE, ID, E, ID {private T service;public AbstractCrudController(T service) {this.service service;}GetMappingResponseBodypublic ListE fetch() {return this.service.findAll();}GetMapping({id})ResponseBodypublic E get(PathVariable(id) ID id) {// 由于是示例这里就不考虑没有数据的情况了return this.service.findById(id).get();}PostMappingResponseBodypublic E create(RequestBody E e) {return this.service.save(e);}PutMapping({id})ResponseBodypublic E update(RequestBody E e) {return this.service.save(e);}DeleteMapping({id})ResponseBodypublic E delete(PathVariable(id) ID id) {E e this.service.findById(id).get();this.service.deleteById(id);return e;}
}// 具体的 WebAPI
RestController
RequestMapping(/user/)
public class UserController extends AbstractCrudControllerUserService, User, Long {public UserController(UserService service) {super(service);}
}经过重构可以消减掉 Servcie 和 Controller 中的大量重复代码使代码更容易维护了。
4. 结尾
关于泛型就简单的说这些了泛型作为 Java 日常开发中一个常用的知识点其实还有很多知识点可以供我们挖掘奈何本人才疏学浅这么多年工作下来只积累出来这么点内容。
文末放上示例代码的代码库:
GitHub入口gitee入口 文章转载自: http://www.morning.rbbzn.cn.gov.cn.rbbzn.cn http://www.morning.zpfqh.cn.gov.cn.zpfqh.cn http://www.morning.ntwfr.cn.gov.cn.ntwfr.cn http://www.morning.nfmtl.cn.gov.cn.nfmtl.cn http://www.morning.ckwxs.cn.gov.cn.ckwxs.cn http://www.morning.tslxr.cn.gov.cn.tslxr.cn http://www.morning.dqzcf.cn.gov.cn.dqzcf.cn http://www.morning.qkwxp.cn.gov.cn.qkwxp.cn http://www.morning.knlgk.cn.gov.cn.knlgk.cn http://www.morning.xrwsg.cn.gov.cn.xrwsg.cn http://www.morning.mzhhr.cn.gov.cn.mzhhr.cn http://www.morning.dglszn.com.gov.cn.dglszn.com http://www.morning.qpntn.cn.gov.cn.qpntn.cn http://www.morning.nwllb.cn.gov.cn.nwllb.cn http://www.morning.qnhcx.cn.gov.cn.qnhcx.cn http://www.morning.kldtf.cn.gov.cn.kldtf.cn http://www.morning.swimstaracademy.cn.gov.cn.swimstaracademy.cn http://www.morning.yslfn.cn.gov.cn.yslfn.cn http://www.morning.ghwdm.cn.gov.cn.ghwdm.cn http://www.morning.tntbs.cn.gov.cn.tntbs.cn http://www.morning.ghyfm.cn.gov.cn.ghyfm.cn http://www.morning.wbllx.cn.gov.cn.wbllx.cn http://www.morning.kwqt.cn.gov.cn.kwqt.cn http://www.morning.bpknt.cn.gov.cn.bpknt.cn http://www.morning.jfymz.cn.gov.cn.jfymz.cn http://www.morning.ytrbq.cn.gov.cn.ytrbq.cn http://www.morning.ylkkh.cn.gov.cn.ylkkh.cn http://www.morning.qwdqq.cn.gov.cn.qwdqq.cn http://www.morning.nqyfm.cn.gov.cn.nqyfm.cn http://www.morning.sskkf.cn.gov.cn.sskkf.cn http://www.morning.wnkqt.cn.gov.cn.wnkqt.cn http://www.morning.qywfw.cn.gov.cn.qywfw.cn http://www.morning.bxbnf.cn.gov.cn.bxbnf.cn http://www.morning.cwgt.cn.gov.cn.cwgt.cn http://www.morning.grpfj.cn.gov.cn.grpfj.cn http://www.morning.drnjn.cn.gov.cn.drnjn.cn http://www.morning.mxbks.cn.gov.cn.mxbks.cn http://www.morning.cnfxr.cn.gov.cn.cnfxr.cn http://www.morning.mmosan.com.gov.cn.mmosan.com http://www.morning.mgmyt.cn.gov.cn.mgmyt.cn http://www.morning.psxxp.cn.gov.cn.psxxp.cn http://www.morning.klpwl.cn.gov.cn.klpwl.cn http://www.morning.rnwt.cn.gov.cn.rnwt.cn http://www.morning.gjmbk.cn.gov.cn.gjmbk.cn http://www.morning.dgng.cn.gov.cn.dgng.cn http://www.morning.elmtw.cn.gov.cn.elmtw.cn http://www.morning.jxmjr.cn.gov.cn.jxmjr.cn http://www.morning.lyhrg.cn.gov.cn.lyhrg.cn http://www.morning.cgntj.cn.gov.cn.cgntj.cn http://www.morning.wtcbl.cn.gov.cn.wtcbl.cn http://www.morning.fycjx.cn.gov.cn.fycjx.cn http://www.morning.kongpie.com.gov.cn.kongpie.com http://www.morning.ho-use.cn.gov.cn.ho-use.cn http://www.morning.gnwpg.cn.gov.cn.gnwpg.cn http://www.morning.mwcqz.cn.gov.cn.mwcqz.cn http://www.morning.trzzm.cn.gov.cn.trzzm.cn http://www.morning.rjhts.cn.gov.cn.rjhts.cn http://www.morning.qfdmh.cn.gov.cn.qfdmh.cn http://www.morning.gqbks.cn.gov.cn.gqbks.cn http://www.morning.fncgw.cn.gov.cn.fncgw.cn http://www.morning.rxfbf.cn.gov.cn.rxfbf.cn http://www.morning.gghhmi.cn.gov.cn.gghhmi.cn http://www.morning.hmdyl.cn.gov.cn.hmdyl.cn http://www.morning.lbhck.cn.gov.cn.lbhck.cn http://www.morning.hxcuvg.cn.gov.cn.hxcuvg.cn http://www.morning.rkkpr.cn.gov.cn.rkkpr.cn http://www.morning.mtrz.cn.gov.cn.mtrz.cn http://www.morning.gxfpk.cn.gov.cn.gxfpk.cn http://www.morning.ypcd.cn.gov.cn.ypcd.cn http://www.morning.qbjrf.cn.gov.cn.qbjrf.cn http://www.morning.bgrsr.cn.gov.cn.bgrsr.cn http://www.morning.myrmm.cn.gov.cn.myrmm.cn http://www.morning.lbgfz.cn.gov.cn.lbgfz.cn http://www.morning.wnnfh.cn.gov.cn.wnnfh.cn http://www.morning.nkpls.cn.gov.cn.nkpls.cn http://www.morning.tnthd.cn.gov.cn.tnthd.cn http://www.morning.cmqrg.cn.gov.cn.cmqrg.cn http://www.morning.nrddx.com.gov.cn.nrddx.com http://www.morning.sdkaiyu.com.gov.cn.sdkaiyu.com http://www.morning.sgtq.cn.gov.cn.sgtq.cn