欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java和Ceylon對(duì)象的構(gòu)造和驗(yàn)證

 更新時(shí)間:2016年11月14日 13:58:13   作者:shanshuiss  
這篇文章主要為大家詳細(xì)介紹了Java和Ceylon對(duì)象的構(gòu)造和驗(yàn)證,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

當(dāng)變換Java代碼為Ceylon代碼時(shí),有時(shí)候我會(huì)遇到一些Java類(lèi)構(gòu)造器混淆了驗(yàn)證與初始化的情形。讓我們使用一個(gè)簡(jiǎn)單但是人為的代碼例子來(lái)說(shuō)明我想闡述的意思。

一些壞代碼

考慮下面的Java類(lèi)。(伙計(jì),不要在家里寫(xiě)這樣的代碼)

public class Period {
 private final Date startDate;
 private final Date endDate;
 //returns null if the given String
 //does not represent a valid Date
 private Date parseDate(String date) {
  ...
 }
 public Period(String start, String end) {
  startDate = parseDate(start);
  endDate = parseDate(end);
 }
 public boolean isValid() {
  return startDate!=null && endDate!=null;
 }
 public Date getStartDate() {
  if (startDate==null) 
   throw new IllegalStateException();
  return startDate;
 }
 public Date getEndDate() {
  if (endDate==null)
   throw new IllegalStateException();
  return endDate;
 }
}

嘿,我之前已經(jīng)警告過(guò),它是人為的。但是,在實(shí)際Java代碼中找個(gè)像這樣的東西實(shí)際上并非不常見(jiàn)。

這里的問(wèn)題在于,即使輸入?yún)?shù)(在隱藏的parseDate()方法中)的驗(yàn)證失敗了,我們還是會(huì)獲得一個(gè)Period的實(shí)例。但是我們獲取的那個(gè)Period不是一個(gè)“有效的”狀態(tài)。嚴(yán)格地說(shuō),我的意思是什么呢?

好吧,假如一個(gè)對(duì)象不能有意義地響應(yīng)公用操作時(shí),我會(huì)說(shuō)它處于一個(gè)非有效狀態(tài)。在這個(gè)例子里,getStartDate() 和getEndDate()會(huì)拋出一個(gè)IllegalStateException異常,這就是我認(rèn)為不是“有意義的”一種情況。

從另外一方面來(lái)看這個(gè)例子,在設(shè)計(jì)Period時(shí),我們這兒出現(xiàn)了類(lèi)型安全的失敗。未檢查的異常代表了類(lèi)型系統(tǒng)中的一個(gè)“漏洞”。因此,一個(gè)更好的Period的類(lèi)型安全的設(shè)計(jì),會(huì)是一個(gè)不使用未檢查的異?!谶@個(gè)例子中意味著不拋出IllegalStateException異常。

(實(shí)際上,在真實(shí)代碼中,我更有可能遇到一個(gè)getStartDate() 方法它不檢查null ,在這個(gè)代碼行之后就會(huì)導(dǎo)致一個(gè)NullPointerException異常,這就更加糟糕了。)

我們能夠很容易地轉(zhuǎn)換上面的Period類(lèi)成為Ceylon形式的類(lèi):

shared class Period(String start, String end) {
 //returns null if the given String
 //does not represent a valid Date
 Date? parseDate(String date) => ... ;
 value maybeStartDate = parseDate(start);
 value maybeEndDate = parseDate(end);
 shared Boolean valid
  => maybeStartDate exists 
  && maybeEndDate exists;
 shared Date startDate {
  assert (exists maybeStartDate);
  return maybeStartDate;
 }
 shared Date endDate {
  assert (exists maybeEndDate);
  return maybeEndDate;
 }
}

當(dāng)然了,這段代碼也會(huì)遇到與原始Java代碼同樣的問(wèn)題。兩個(gè)assert符號(hào)沖著我們大喊,在代碼的類(lèi)型安全中有一個(gè)問(wèn)題。

使Java代碼變得更好

Java里我們?cè)趺锤倪M(jìn)這段代碼呢?好吧,這兒就是一個(gè)例子關(guān)于Java飽受詬病的已檢查異常會(huì)是一個(gè)非常合理的解決方法!我們可以稍微修改下Period來(lái)從它的構(gòu)造器中拋出一個(gè)已檢查的異常:

public class Period {
 private final Date startDate;
 private final Date endDate;
 //throws if the given String
 //does not represent a valid Date
 private Date parseDate(String date)
   throws DateFormatException {
  ...
 }
 public Period(String start, String end) 
   throws DateFormatException {
  startDate = parseDate(start);
  endDate = parseDate(end);
 }
 public Date getStartDate() {
  return startDate;
 }
 public Date getEndDate() {
  return endDate;
 }
}

現(xiàn)在,使用這個(gè)解決方案,我們就不會(huì)獲取一個(gè)處于非有效狀態(tài)的Period,實(shí)例化Period的代碼會(huì)由編譯器負(fù)責(zé)去處理無(wú)效輸入的情形,它會(huì)捕獲一個(gè)DateFormatException異常。

try {
 Period p = new Period(start, end);
 ...
}
catch (DateFormatException dfe) {
 ...
}

這是一個(gè)對(duì)已檢查異常不錯(cuò)的、完美的、正確的使用,不幸的是我?guī)缀鹾苌倏吹絁ava代碼像上面這樣使用已檢查異常。

使Ceylon代碼變得更好

那么Ceylon怎么樣呢?Ceylon沒(méi)有已檢查異常,因而我們需要尋找一個(gè)不同的解決方式。典型地,在Java調(diào)用一個(gè)函數(shù)會(huì)拋出一個(gè)已檢查異常的情形中,Ceylon會(huì)調(diào)用函數(shù)返回一個(gè)聯(lián)合類(lèi)型。因?yàn)?,一個(gè)類(lèi)的初始化不返回除了類(lèi)自己外的任何類(lèi)型,我們需要提取一些混合的初始化/驗(yàn)證的邏輯來(lái)使其成為一個(gè)工廠函數(shù)。

//returns DateFormatError if the given 
//String does not represent a valid Date
Date|DateFormatError parseDate(String date) => ... ;
shared Period|DateFormatError parsePeriod
  (String start, String end) {
 value startDate = parseDate(start);
 if (is DateFormatError startDate) {
  return startDate;
 }
 value endDate = parseDate(end);
 if (is DateFormatError endDate) {
  return endDate;
 }
 return Period(startDate, endDate);
}
shared class Period(startDate, endDate) {
 shared Date startDate;
 shared Date endDate;
}

根據(jù)類(lèi)型系統(tǒng),調(diào)用者有義務(wù)去處理DateFormatError:

value p = parsePeriod(start, end);
if (is DateFormatError p) {
 ...
}
else {
 ...
}

或者,如果我們不關(guān)心給定日期格式的實(shí)際問(wèn)題(這是有可能的,假定我們工作的初始化代碼丟失了那個(gè)信息),我們可以使用Null而不是DateFormatError:

//returns null if the given String 
//does not represent a valid Date
Date? parseDate(String date) => ... ;
shared Period? parsePeriod(String start, String end)
 => if (exists startDate = parseDate(start), 
   exists endDate = parseDate(end))
  then Period(startDate, endDate)
  else null;
shared class Period(startDate, endDate) {
 shared Date startDate;
 shared Date endDate;
}

至少可以說(shuō),使用工廠函數(shù)的方法是優(yōu)秀的,因?yàn)橥ǔ?lái)說(shuō)在驗(yàn)證邏輯和對(duì)象初始化之間它具有更好的隔離。這點(diǎn)在Ceylon中特別有用,在Ceylon中,編譯器在對(duì)象初始化邏輯中添加了一些非常嚴(yán)厲的限制,以保證對(duì)象的所有領(lǐng)域僅被賦值一次。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot系列教程之dubbo和Zookeeper集成方法

    SpringBoot系列教程之dubbo和Zookeeper集成方法

    這篇文章主要介紹了SpringBoot系列教程之dubbo和Zookeeper集成方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java?超基礎(chǔ)講解String的使用

    Java?超基礎(chǔ)講解String的使用

    字符串廣泛應(yīng)用?在?Java?編程中,在?Java?中字符串屬于對(duì)象,Java?提供了?String?類(lèi)來(lái)創(chuàng)建和操作字符串,讓我們一起來(lái)了解它
    2022-04-04
  • JFinal實(shí)現(xiàn)偽靜態(tài)的方法

    JFinal實(shí)現(xiàn)偽靜態(tài)的方法

    JFinal 是基于 Java 語(yǔ)言的極速 WEB + ORM 框架,其核心設(shè)計(jì)目標(biāo)是開(kāi)發(fā)迅速、代碼量少、學(xué)習(xí)簡(jiǎn)單、功能強(qiáng)大、輕量級(jí)、易擴(kuò)展、Restful。這篇文章主要介紹了JFinal實(shí)現(xiàn)偽靜態(tài),需要的朋友可以參考下
    2018-04-04
  • IDEA消除指定警告的兩種方法小結(jié)

    IDEA消除指定警告的兩種方法小結(jié)

    有時(shí)候IDEA會(huì)代碼中給出一些我們不需要的警告,看起來(lái)就很不美觀,本文主要介紹了IDEA消除指定警告的兩種方法,感興趣的可以了解一下
    2023-08-08
  • Java中的synchronized?優(yōu)化方法之鎖膨脹機(jī)制

    Java中的synchronized?優(yōu)化方法之鎖膨脹機(jī)制

    這篇文章主要介紹了Java中的synchronized?優(yōu)化方法之鎖膨脹機(jī)制,鎖膨脹機(jī)制是提升?synchronized?性能最有利的方法之一,下面我們就來(lái)看看什么事鎖膨脹及鎖膨脹的各種細(xì)節(jié)
    2022-05-05
  • Java中List、Set、Map的區(qū)別和實(shí)現(xiàn)方式示例代碼

    Java中List、Set、Map的區(qū)別和實(shí)現(xiàn)方式示例代碼

    這篇文章主要介紹了Java中List、Set、Map的區(qū)別和實(shí)現(xiàn)方式示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • Java線程中start和run方法全面解析

    Java線程中start和run方法全面解析

    這篇文章主要介紹了Java線程中start和run方法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-08-08
  • java之jvm加載器例舉

    java之jvm加載器例舉

    在本篇文章里小編給大家介紹了關(guān)于java之jvm加載器例舉內(nèi)容,對(duì)此有需要的程序員朋友們可以參考下。
    2021-03-03
  • 深入淺析Java中普通代碼塊、構(gòu)造代碼塊與靜態(tài)代碼塊

    深入淺析Java中普通代碼塊、構(gòu)造代碼塊與靜態(tài)代碼塊

    這篇文章主要介紹了Java中普通代碼塊、構(gòu)造代碼塊與靜態(tài)代碼塊的相關(guān)資料,靜態(tài)代碼塊>Main()>構(gòu)造代碼塊 。非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-08-08
  • java書(shū)店系統(tǒng)畢業(yè)設(shè)計(jì) 用戶(hù)模塊(3)

    java書(shū)店系統(tǒng)畢業(yè)設(shè)計(jì) 用戶(hù)模塊(3)

    這篇文章主要介紹了java書(shū)店系統(tǒng)畢業(yè)設(shè)計(jì),第三步系統(tǒng)總體設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10

最新評(píng)論