中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

俄羅斯外貿(mào)常用網(wǎng)站海淀區(qū)seo搜索引擎

俄羅斯外貿(mào)常用網(wǎng)站,海淀區(qū)seo搜索引擎,做網(wǎng)站工資待遇如何,wordpress3.1.3漏洞1. 前言 泛型編程自從 Java 5.0 中引入后已經(jīng)超過15個年頭了。對于現(xiàn)在的 Java 碼農(nóng)來說熟練使用泛型編程已經(jīng)是家常便飯的事情了。所以本文就在不對泛型的基礎(chǔ)使用在做說明了。 如果你還不會使用泛型的話,可以參考下面兩個鏈接 Java 泛型詳解The Java? Tutorial…

1. 前言

泛型編程自從 Java 5.0 中引入后已經(jīng)超過15個年頭了。對于現(xiàn)在的 Java 碼農(nóng)來說熟練使用泛型編程已經(jīng)是家常便飯的事情了。所以本文就在不對泛型的基礎(chǔ)使用在做說明了。 如果你還不會使用泛型的話,可以參考下面兩個鏈接

  • Java 泛型詳解
  • The Java? Tutorials (Lesson: Generics)

這篇文章就簡答聊一下,我實(shí)際在開發(fā)工作中很少用的到泛型方法這個知識點(diǎn),以及在實(shí)際項(xiàng)目中有哪些東西會使用到泛型。

2. 泛型方法

在閱讀代碼的時候我們經(jīng)常會看到下面這樣的方法 (這段代碼摘自 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);Iterator<E> 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 關(guān)鍵字后面的那個 <T> 就是用來標(biāo)記這個方法是一個泛型方法。 那什么是泛型方法呢。

官方的解釋是這樣的

Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.

通俗點(diǎn)來將就是將一個方法泛型化,讓一個普通的類的某一個方法具有泛型功能。 如果在一個泛型類中增加一個泛型方法,那這個泛型方法就可以有一套獨(dú)立于這個類的泛型類型。

通過一個簡單的例子, 我們來看看

/*** GenericClass 這個泛型類是一個簡單的套皮的 HashMap*/
public class GenericClass<K, V> {private Map<K, 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 可以接受一個全新的、作用域只限本函數(shù)的泛型類型Tpublic <T> T genericMethod(T t) {return t;}}

實(shí)際使用起來

GenericClass<String, Integer> map = new GenericClass<>();
// put 和 get 方法的參數(shù)必須使用定義時指定的 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 在它的實(shí)現(xiàn)中就提供了兩個版本,其中一個就是泛型方法的版本

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable 
{// 這是一個普通版本,返回一個Object的數(shù)組public Object[] toArray() {return Arrays.copyOf(elementData, size);}// 這是一個泛型方法的版本,將容器里存儲的元素輸出到 T[] 數(shù)組中。 其中 T 必須是 E 的父類,否則 System.arraycopy 會拋出 ArrayStoreException 異常      public <T> T[] toArray(T[] a) {if (a.length < size)// Make a new array of a's 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;}
}

泛型方法總體上來說就是可以給與現(xiàn)有的方法實(shí)現(xiàn)上,增加一個更加靈活的實(shí)現(xiàn)可能。

3. 實(shí)戰(zhàn)應(yīng)用

在實(shí)際的項(xiàng)目中,對于泛型的使用,除了像傾倒垃圾一樣往泛型容易里塞各種 java bean 和其他泛型對象。還能怎么使用泛型呢?

我們在實(shí)際的一些項(xiàng)目中,會對數(shù)據(jù)庫中的一些表(多數(shù)時候是全部)先實(shí)現(xiàn) CRUD (Create, Read, Update, Delete)的操作,并從這些操作中延伸出一些簡單的 REST 風(fēng)格的 WebAPI 接口,然后才會根據(jù)實(shí)際業(yè)務(wù)需要實(shí)現(xiàn)一些更復(fù)雜的業(yè)務(wù)接口。

大體上會是下面這個樣子。


// 這是一個簡單的 Entity 對象
// 通常現(xiàn)在的 Java 應(yīng)用都會使用到 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 JpaRepository<User, Long> {
}// 在來是一個訪問 User 資源的 Service 和他的實(shí)現(xiàn)
public interface UserService {List<User> findAll();Optional<User> 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 List<User> findAll() {return this.dao.findAll();}@Overridepublic Optional<User> 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;}@GetMapping@ResponseBodypublic List<User> fetch() {return this.userService.findAll();}@GetMapping("{id}")@ResponseBodypublic User get(@PathVariable("id") Long id) {// 由于是示例這里就不考慮沒有數(shù)據(jù)的情況了return this.userService.findById(id).get();}@PostMapping@ResponseBodypublic 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;}
}

大致一個表的一套相關(guān)接口就是這個樣子的。如果你的數(shù)據(jù)庫中有大量表的話,而且每個表都需要提供 REST 風(fēng)格的 WebAPI 接口的話,那么這將是一個相當(dāng)枯燥的而又及其容易出錯的工作。

為了不讓這項(xiàng)枯燥而又容易犯錯的工作占去我們寶貴的私人時間,我們可以通過泛型和繼承的技巧來重構(gòu)從 Service 層到 Controller 的這段代碼(感謝 spring-data 提供了 JpaRepository, 讓我們不至于從 DAO 層重構(gòu))

3.1 Service 層的重構(gòu)

首先是 Service 接口的重構(gòu),我們 Service 層接口就是定義了一組 CRUD 的操作,我們可以將這組 CRUD 操作抽象到一個父接口,然后所有 Service 層的接口都將繼承自這個父接口。而接口中出現(xiàn)的 Entity 和主鍵的類型(上例中 User 的主鍵 id 的類型是 Long)就可以用泛型來展現(xiàn)。

// 這里泛型表示 E 來指代 Entity, ID 用來指代 Entity 主鍵的類型
public interface ICrudService<E, ID> {List<E> findAll();Optional<E> findById(ID id);E save(E e);void deleteById(ID id);
}// 然后 Service 層的接口,就可以簡化成這樣
public interface UserService extends ICrudService<User, Long> {
}

同樣 Service 層的實(shí)現(xiàn)也可以使用相似的方法具體實(shí)現(xiàn)可以抽象到一個基類中。

// 相比 ICrudService 這里有多了一個泛型 T 來代表 Entity 對應(yīng)的 DAO, 我們的每一個 DAO 都繼承自
// spring-data 的 JpaRepository 所以,這里可以使用到泛型的邊界
public abstract class AbstractCrudService<T extends JpaRepository<E, ID>, E, ID> {private T dao;public AbstractCrudService(T dao) {this.dao = dao;}public List<E> findAll() {return this.dao.findAll();}public Optional<E> 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 的實(shí)現(xiàn)類可以簡化成這樣
@Service
public class UserServiceImpl extends AbstractCrudService<UserDao, User, Long> implements UserService {public UserServiceImpl(UserDao dao) {supper(dao);}
}

同樣我們可以通過相同的方法來對 Controller 層進(jìn)行重構(gòu)

// Controller 層的基類
public abstract class AbstractCrudController<T extends ICrudService<E, ID>, E, ID> {private T service;public AbstractCrudController(T service) {this.service = service;}@GetMapping@ResponseBodypublic List<E> fetch() {return this.service.findAll();}@GetMapping("{id}")@ResponseBodypublic E get(@PathVariable("id") ID id) {// 由于是示例這里就不考慮沒有數(shù)據(jù)的情況了return this.service.findById(id).get();}@PostMapping@ResponseBodypublic 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 AbstractCrudController<UserService, User, Long> {public UserController(UserService service) {super(service);}
}

經(jīng)過重構(gòu)可以消減掉 Servcie 和 Controller 中的大量重復(fù)代碼,使代碼更容易維護(hù)了。

4. 結(jié)尾

關(guān)于泛型就簡單的說這些了,泛型作為 Java 日常開發(fā)中一個常用的知識點(diǎn),其實(shí)還有很多知識點(diǎn)可以供我們挖掘,奈何本人才疏學(xué)淺,這么多年工作下來,只積累出來這么點(diǎn)內(nèi)容。

文末放上示例代碼的代碼庫:

  • GitHub入口
  • gitee入口
http://www.risenshineclean.com/news/33163.html

相關(guān)文章:

  • 源代碼管理網(wǎng)站百度推廣優(yōu)化方案
  • 佛山外貿(mào)網(wǎng)站設(shè)計(jì)高手優(yōu)化網(wǎng)站
  • 四川高速公路建設(shè)集團(tuán)網(wǎng)站網(wǎng)站設(shè)計(jì)與開發(fā)
  • 淘寶裝修免費(fèi)模板有哪些網(wǎng)站網(wǎng)站制作公司咨詢
  • 凡科專屬網(wǎng)站免費(fèi)注冊外鏈生成工具
  • 哪個網(wǎng)站做推銷產(chǎn)品品牌seo主要做什么
  • 貴州網(wǎng)站建設(shè)360指數(shù)查詢工具
  • 做政府網(wǎng)站話術(shù)seo系統(tǒng)是什么意思
  • ps做網(wǎng)站需要幾個畫布lol今日賽事直播
  • 北京北京網(wǎng)站建設(shè)seo是什么意思啊
  • 網(wǎng)站客戶端制作鄭州網(wǎng)絡(luò)推廣培訓(xùn)
  • 網(wǎng)站建設(shè)制作 企業(yè)站開發(fā)哪家好制作網(wǎng)站需要多少費(fèi)用
  • 關(guān)鍵詞優(yōu)化排名首頁安徽網(wǎng)站優(yōu)化
  • 個人備案經(jīng)營網(wǎng)站優(yōu)化設(shè)計(jì)三要素
  • 做批手表批發(fā)發(fā)的網(wǎng)站站外推廣怎么做
  • 找個為公司做網(wǎng)站的班級優(yōu)化大師下載
  • 網(wǎng)站群管理建設(shè)關(guān)鍵詞一般是指什么
  • 外貿(mào)工廠 網(wǎng)站建設(shè)seo代理
  • 網(wǎng)站建設(shè)維護(hù)成本百度指數(shù)官網(wǎng)移動版
  • 石家莊 外貿(mào)網(wǎng)站建設(shè)公司排名網(wǎng)絡(luò)營銷項(xiàng)目
  • 哪里網(wǎng)站用vue.js做的網(wǎng)站排名查詢平臺
  • 網(wǎng)站建設(shè) 大公司小公司軟文發(fā)布軟件
  • 做網(wǎng)站怎樣賺賣流量中國國家培訓(xùn)網(wǎng)正規(guī)嗎
  • 東莞做網(wǎng)站的公司有哪些谷歌網(wǎng)址
  • 個體戶做網(wǎng)站有優(yōu)勢嗎google谷歌搜索主頁
  • 網(wǎng)站建設(shè)方面的優(yōu)劣勢分析上海網(wǎng)絡(luò)營銷
  • 波波網(wǎng)站建設(shè)域名查詢網(wǎng)
  • 圖片瀑布流網(wǎng)站鄭州百度網(wǎng)站優(yōu)化排名
  • 怎樣用linux做網(wǎng)站微信廣告投放推廣平臺
  • 工藝品網(wǎng)站怎么做提高網(wǎng)站排名