[轉載] java避免空指標異常_第1部分:在現代Java應用程式中避免空指標異常

ld909發表於2020-12-11

參考連結: Java的instanceof及其應用

java避免空指標異常

 

  

   

    

      空做與不做 (Null do’s and don’ts) 

     In the talk Null References: The Billion Dollar Mistake, Sir Tony Hoare describes implementing null references as a part of the ALGOL programming language, as well, a billion-dollar mistake. Authoritative programming books like Clean Code: A Handbook of Agile Software Craftsmanship advise you to use null as little as possible, while the book Bug Patterns In Java dedicates three whole chapters to problems stemming from null-values. The StackOverflow topic “What is a null pointer exception and how do I fix it” has 3 million views. It is easy to get anxious working with null-values!

      在演講“ 空引用:十億美元的錯誤”中 ,Tony Hoare爵士描述了將空引用作為ALGOL程式語言的一部分以及十億美元的錯誤。 權威程式設計書籍喜歡乾淨程式碼:敏捷軟體Craft.io的手冊建議你使用零儘可能少,而這本書的錯誤模式在Java致力於整整三章從空值而引起的問題。 StackOverflow主題“ 什麼是空指標異常以及如何解決它 ”有300萬個檢視。 急於使用空值很容易!  

     I’m not one to tell Turing-award winners like Hoare how to design programming languages, but I will say that I don’t think null is inherently bad. I will discuss why that is, when you should and shouldn’t use null, and how to elegantly handle null-values over in the following two blog posts. In the current post, I will present my musings on using null values and in the next blog post (going online Friday 21st August), we’re going to look at the practical application of some techniques for working with null, including recent features in Java 8.

      我不是要告訴像Hoare這樣的圖靈獎獲獎者如何設計程式語言,但是我會說,我認為null並不是天生就不好的。 我將在以下兩篇部落格文章中討論為什麼這樣做,何時不應該使用null,以及如何優雅地處理null值。 在當前文章中,我將介紹有關使用null值的想法,在下一篇部落格文章(8月21日,星期五線上)中,我們將研究一些使用null的技術的實際應用,包括Java 8。  

     While the posts are Java-centric, the underlying principles and discussion should extend to object-oriented programming languages in general. The blog posts are primarily intended for less experienced programmers and anybody else who might be intimidated by null, but old dogs might learn some new tricks too.

      儘管這些帖子是以Java為中心的,但總體而言,基本原理和討論應該擴充套件到物件導向的程式語言。 該部落格文章主要面向經驗不足的程式設計師以及可能被null嚇倒的其他任何人,但是老狗也可能會學習一些新技巧。  

      無效的危險 (The dangers of null) 

     

      

       

        

         

          

         

        

       

      

     

     Null is a special value as it is not associated with any type (feel free to verify with instanceof against every other class in the JRE) and will happily take the place of any other object in variable assignments and method calls. This is what gives null its two dangerous properties:

      Null是一個特殊值,因為它不與任何型別關聯(可以通過instanceof與JRE中的每個其他類進行驗證),並且很樂意在變數賦值和方法呼叫中代替任何其他物件。 這就是使null具有兩個危險特性的原因:  

     Every complex-typed return value may be null 每個複雜型別的返回值都可以為null Every complex-typed parameter value may be null 每個複雜型別的引數值都可以為null 

     As a result, any return value or parameter object is a NullPointerException (NPE) waiting to happen if not handled carefully.

      結果,任何返回值或引數物件都是NullPointerException(NPE),如果不仔細處理就會等待發生。  

     Is the solution then to check every return value and parameter for null values? It should be obvious that this is a bad idea. First, it clutters the code with null-checks. Secondarily, it forces the developer to use precious time on considering the right way to handle null-values that never occurs, and the null-checks will mislead other developers.

      那麼解決方案是檢查每個返回值和引數是否為空值嗎? 很明顯,這是一個壞主意。 首先,它使用空檢查使程式碼混亂。 其次,它迫使開發人員花費寶貴的時間來考慮正確的方法來處理從未發生的空值,並且空檢查會誤導其他開發人員。  

     Is the solution to never assign null to any values? Well, no. As highlighted by the fact that most programming languages have the concept of an empty value (nil, undefined, None, void, etc), having a general value for nothing is tremendously useful.

      解決方案是永遠不要為任何值分配null嗎? 好吧,不。 正如大多數程式語言都具有空值(nil,undefined,None,void等)這一事實所強調的那樣,無所作為的通用值是非常有用的。  

     An error in a while-loop condition can create an infinite loop in any program, but it doesn’t make while-loops inherently bad. It would be similarly misguided to think that null is always bad just because misuse can lead to errors. Null is the most natural value to express certain things, but also a very poor value to express others. The competent developer must know when that is and isn’t. In the succeeding section, I will show you where that is.

      while迴圈條件中的錯誤可以在任何程式中建立無限迴圈,但不會使while迴圈固有地變壞。 同樣地,認為null總是很糟糕也僅僅因為濫用會導致錯誤,這是錯誤的。 空是表達某些事物的最自然的價值,也是表達其他事物的非常差的價值。 勝任的開發人員必須知道什麼時候該是什麼。 在接下來的部分中,我將向您展示該位置。  

      何時使用null,何時不使用null (When to use null and when not to) 

     In this part, I will examine the scenarios in which null are returned from and passed to methods, discuss some of the traditional alternatives (i.e. pre-Java 8) and argue why using a built-in empty type like null is the best solution in some cases.

      在這一部分中,我將研究從方法返回null並將其傳遞給方法的場景,討論一些傳統的替代方法(即Java 8之前的版本),並說明為什麼使用內建的空型別(如null)是最佳的解決方案,某些情況下。  

      返回null (Returning null) 

     One of the core philosophies of object-oriented programming is to model the concepts of the business domain in which our software operates. We do this by defining classes that correspond to these real-life concepts and their attributes. I think it’s meaningful to consider these types of classes separately from other types, when it comes to using null values.

      物件導向程式設計的核心思想之一是為我們的軟體在其中執行的業務領域的概念建模。 為此,我們定義了與這些現實概念及其屬性相對應的類。 我認為在使用null值時,將這些型別的類與其他型別分開考慮是有意義的。  

     In the project I work on, the Columna electronic patient record system, we have classes that represent concepts in a hospital workflow, like patients, medications, physicians, hospital units, admissions, etc. As a part of modelling any domain, there are cases where we need to allow something to be nothing. For instance, assume that we have a class to represent an admission with attributes that describes the admission, like the hospital unit where the patient is admitted, the reason for admission, the time of admission, etc. Similarly, we might have a class that represents a patient that holds attributes like name and social security number. At any given point, a patient may or may not be admitted. More formally, we have a has-a relation with a cardinality of 0..1.

      在我從事的專案Columna電子病歷系統中,我們有代表醫院工作流程中概念的類,例如患者,藥物,醫生,醫院單位,住院等。作為對任何域建模的一部分,有一些案例在這裡我們需要允許什麼都不是。 例如,假設我們有一個類別來表示一個具有描述入場的屬性的入場,例如入院患者的醫院單位,入院原因,入院時間等。類似地,我們可能會有一個代表擁有姓名和社會保險號等屬性的患者。 在任何給定的時間點,患者可能會或可能不會被接納。 更正式地講,我們具有基數為0.1的has-a關係。  

     Assume a method that retrieves admission information in a database for a given patient:

      假設一種方法可以檢索資料庫中給定患者的入院資訊:  

     public Admission getAdmission(Patient patient);

     What should the method return for the patient who is not admitted if not null? Is there a more precise value to express this? I’d argue that there isn’t.

      如果不為空,則該方法應返回給未入院的患者? 有沒有更精確的價值來表達這一點? 我認為沒有。  

     There are many other scenarios, where an object from the domain is directly associated with optional values as attributes. An object representing a medication holds values such as the medication name, the form of the medication, the strength, the active drug, etc. But medications are incredibly diverse, ranging from antibacterial creams to cannabis teas and not all of the attributes apply to each. Again, returning null for a missing attribute seems like an obvious choice to communicate that value is allowed to be missing. Is there a better alternative?

      在許多其他情況下,域中的物件與可選值作為屬性直接關聯。 代表藥物的物件具有諸如藥物名稱,藥物形式,強度,活性藥物等值。但是藥物的種類繁多,從抗菌霜到大麻茶,並且並非所有屬性都適用於每種藥物。 同樣,為缺少的屬性返回null似乎是傳達允許值丟失的明顯選擇。 有更好的選擇嗎?  

     Some advocate using the so-called Null Object design pattern instead of null. The basic idea is to implement a hollow class with none or little functionality — the null object — that can be used in place of the class that holds the actual functionality. The pattern is best exemplified with a scenario, where you must recursively traverse a binary tree data structure to find the sum of the value of each node. To do so, you essentially run a depth-first search and recursively sum the value of the left subtree with the right subtree in every node.

      有人主張使用所謂的空物件   設計模式而不是null。 基本思想是實現一個沒有任何功能或只有很少功能的空類(空物件),該空類可以代替擁有實際功能的類。 該模式最好以一種場景為例,在這種情況下,您必須遞迴遍歷二叉樹資料結構以找到每個節點的值之和。 為此,您實際上要進行深度優先搜尋,然後在每個節點中遞迴將左子樹的值與右子樹的值相加。  

     A search tree is typically implemented such that every node in a search tree has a left and a right child that is either a node themselves or an empty leaf node. If the tree representation uses null for leaf notes, you will have to explicitly check for null children to stop recursing at a leaf node and to prevent trying to get the value of the node. Instead, you should define a Node interface with a simple getValue() method and implement it in the class representing a node that computes the value by summing the getValue() values of the children (see figure below). Implement the same interface in a class representing a node and let the leaf class return 0 when called. Now, we no longer have to distinguish code-wise between a leaf or a node; the need for an explicit check for null goes away and so does the risk of an NPE.

      通常實現搜尋樹,以使搜尋樹中的每個節點都具有左右子節點,該子節點既可以是節點本身,也可以是空葉節點。 如果樹表示形式對葉註釋使用null,則必須顯式檢查是否有null子代,以停止在葉節點處遞迴併防止嘗試獲取該節點的值。 相反,您應該使用簡單的getValue()方法定義一個Node介面,並在表示該節點的類中實現該介面,該節點通過將子代的getValue()值相加來計算值(請參見下圖)。 在代表節點的類中實現相同的介面,並讓葉類在呼叫時返回0。 現在,我們不再需要在葉或節點之間按程式碼區分; 顯式檢查是否為null的需求消失了,NPE的風險也消失了。  

     

      

       

        

         

          

         

        

       

      

      

       The Null object pattern applied to a tree structure

      

      

        空物件模式應用於樹形結構 

      

     

     To apply the pattern for the admission example above, we would need to create an Admission interface. We would then define an AdmissionImpl class for when we can return actual admission data and an AdmissionNullObjectImpl for when we can’t. This would allow the getAdmission()-method to return either the real AdmissionImpl or a AdmissionNullObjectImpl.As the calling code uses the shared Admission type, we can treat both objects the same with no risk of exceptions or without cluttering the code with checks for null handling.

      要將模式應用到上面的准入示例,我們需要建立一個准入介面。 然後,我們將定義一個AdmissionImpl類(用於何時可以返回實際的准入資料),以及一個AdmissionNullObjectImpl(用於何時不能返回)。 這將允許getAdmission()方法返回真實的AdmissionImpl或AdmissionNullObjectImpl。由於呼叫程式碼使用共享的Admission型別,因此我們可以將兩個物件視為相同,沒有異常風險,也不會因檢查null而使程式碼混亂處理。  

     However, I personally find it very hard to find usages for the pattern in typical production codebases, where the logic is often far more complex than a simple accumulation of numbers. Patterns exist to simplify solutions, but add complexity with no benefits when used inappropriately.

      但是,我個人發現很難在典型的生產程式碼庫中找到模式的用法,在這種程式碼庫中,邏輯通常比簡單的數字累加要複雜得多。 存在模式可以簡化解決方案,但是如果使用不當,則會增加複雜性而沒有任何好處。  

     What is the AdmissionNullObject class supposed to return when it doesn’t hold any real data? What should it return instead of a location object when getLocation() is called? What is the natural start date to return?

      當AdmissionNullObject類不包含任何實際資料時應該返回什麼? 呼叫getLocation()時,它應該返回什麼而不是位置物件? 返回的自然開始日期是什麼?  

     In many cases, you’d have to write code that at some point needs to check for something to handle fake values, so why not just have a null check in the first place and avoid defining extra complexity-increasing classes? There are cases where the pattern works great, but I feel they are rare in the real world, as it can only be used for objects with methods with void values or where you can return something that naturally fits into the flow of the surrounding code.

      在許多情況下,您必須編寫某些時候需要檢查某些內容以處理假值的程式碼,那麼為什麼不首先進行空檢查並避免定義額外的複雜性類呢? 在某些情況下,模式效果很好,但是我覺得它們在現實世界中很少見,因為它只能用於具有空值的方法的物件,或者可以返回自然適合周圍程式碼流的物件。  

     Another alternative, which is sometimes used, is to use the empty string instead of null when an attribute is represented as a simple string. This removes the risk of NPEs, but you’ll likely need just as many checks to handle the empty value correctly as with null. Additionally, the semantics are different: An empty string represents a string with an empty value — null represents nothing. This becomes relevant if an application needs to distinguish between whether a user has not provided information vs. the user has entered some information in the form of the empty string value. You remove the risk of an NPE, but at the cost of using a somewhat misleading value.

      有時使用的另一種替代方法是,當屬性表示為簡單字串時,使用空字串而不是null。 這消除了NPE的風險,但是您可能需要與使用null一樣多的檢查才能正確處理空值。 此外,語義也有所不同:空字串表示具有空值的字串-null表示什麼。 如果應用程式需要區分使用者是否提供資訊與使用者是否以空字串值形式輸入了一些資訊,這將變得很重要。 您消除了NPE的風險,但以使用具有誤導性的價值為代價。  

     Now let’s consider using null in the code that does not model real-life concepts. Most classes in an object-oriented code base have no counterpart in real life and only exist as an abstraction for infrastructure, processing and transformation and to group related functionality. Whether instantiations of these should be allowed to be represented with a null-value is less clear-cut. If we call a getter for a value with a very abstract type like TwoFactorComplexStrategyHandlerDelegateBean would we expect it to be null? Probably not. With a class that represents a concept from the real world, we can make an educated guess. But these types of classes leave us no chance. We can only know from reading the code. For that reason, returning null in place of these types should be avoided as people rarely have a reason to expect a null value. If you don’t expect null, why would you put in the effort to ensure your code is null-safe?

      現在,讓我們考慮在不對真實概念建模的程式碼中使用null。 物件導向的程式碼庫中的大多數類在現實生活中沒有對應物件,而僅作為基礎結構,處理和轉換以及與組相關的功能的抽象存在。 是否應該允許使用空值來表示這些例項的例項不太明確。 如果我們為具有非常抽象的型別(例如TwoFactorComplexStrategyHandlerDelegateBean)的值呼叫吸氣劑,我們會期望它為null嗎? 可能不是。 通過代表現實世界中概念的課程,我們可以做出有根據的猜測。 但是這些型別的課程讓我們沒有機會。 我們只能從閱讀程式碼中知道。 因此,應避免返回null代替這些型別,因為人們很少有理由期望null值。 如果您不期望null,為什麼還要努力確保程式碼是null安全的?  

     These objects that shouldn’t be represented by null are de facto. Not only in our own codebase but also in the JRE, libraries and frameworks. It’s problematic, but how problematic? It is important that even though we should try to minimize the usage of null, we shouldn’t trade having fewer null values for codebases full of complex workarounds to prevent values from becoming null. As I’ve discussed above, the alternatives are not always so great. There are, however, some cases of returning null that are easily avoidable, yet frequently seen. A returned null value for these classes often means that something is fishy. For instance, null is sometimes returned from getter-methods, where an object cannot be created due to some particular circumstance, like a server call in the method responding with an error. The method handles the error by logging in a catch-statement, and, instead of instantiating some object, returns null. Or when a method has certain preconditions for the parameters that are not met by the arguments, so again it just returns null. There’s an easy fix for these. An exception should be used to indicate that something is wrong and force the calling code into dealing with it. Returning null in these scenarios is misleading, does not ensure that the problem is handled and might forward the problem to some other part of the code, where it would have been better to fail fast.

      這些不應該由null表示的物件實際上是 。 不僅在我們自己的程式碼庫中,而且在JRE,庫和框架中。 有問題,但是有問題嗎? 重要的是,即使我們應該嘗試最小化null的使用,我們也不應該為具有複雜變通辦法的程式碼庫使用較少的null值進行交易,以防止值變為null。 正如我上面所討論的,替代方案並不總是那麼好。 但是,有些返回空值的情況很容易避免,但很常見。 這些類返回的空值通常意味著有些東西是可疑的。 例如,有時會從getter方法返回null,在該方法中,由於某些特殊情況而無法建立物件,例如方法中響應錯誤的伺服器呼叫。 該方法通過登入catch語句來處理錯誤,並且不例項化某些物件,而是返回null。 或者,當某個方法具有引數無法滿足的某些特定前提條件時,那麼它再次返回null。 有一個簡單的解決方法。 應該使用異常來表明出了點問題,並迫使呼叫程式碼對其進行處理。 在這些情況下,返回null會產生誤導,不能確保問題得到解決,並且可能會將問題轉發到程式碼的其他部分,而在其他情況下最好還是快速失敗 。  

     Another wrong usage of null is representing a has-a relation with a cardinality of 0..* (earlier I talked about 0..1 relations). Going back to our patient object, a patient may have one or more relatives registered. Or none. We would usually represent this with a list. However, I often see that people return null when there is no data to populate a list or other Collection types. Null is similarly used as an argument to methods in place of missing collections. Using null for this is bad for the following reasons. It is misleading, as the cardinality is perfectly representable with a collection. By assigning null to a Collection type, you only introduce unnecessary risk in your code. A for-loop based on a collection does nothing if the collection is empty, otherwise, it iterates over each element and does something. If you let a collection be null, you express the same thing as an empty list — no data to process here — however, you now need to ensure that there’s a null-check in every downstream method where you want to use the collection to avoid an NPE. Call methods with empty collections, when there is no data to provide. It’s as easy as calling Collections.emptyList(), emptyMap(), emptySet(), etc. Not a lot more work than declaring null, but a lot better.

      空的另一種錯誤用法是表示具有-A為0的基數.. *(前面我談到0..1關係)的關係。 回到我們的患者物件,患者可能已經註冊了一個或多個親戚。 還是沒有。 我們通常用列表來表示。 但是,我經常看到,當沒有資料可填充列表或其他Collection型別時,人們返回null。 類似地,將Null用作方法的引數來代替缺少的集合。 由於以下原因,為此使用null是不利的。 這是一種誤導,因為基數完全可以用集合表示。 通過將null分配給Collection型別,只會在程式碼中引入不必要的風險。 如果集合為空,則基於集合的for迴圈不執行任何操作,否則,它將遍歷每個元素並執行某些操作。 如果讓集合為空,則表示與空列表相同的內容(此處沒有要處理的資料),但是,現在您需要確保在每個要使用集合的下游方法中都進行空檢查,以避免NPE。 當沒有資料可提供時,呼叫具有空集合的方法。 就像呼叫Collections.emptyList(),emptyMap(),EmptySet()等一樣簡單。與宣告null相比,它的工作並不多,但更好。  

      傳遞空引數 (Passing null-parameters) 

     It follows from the preceding section that it would be acceptable to use null arguments, when calling methods with domain-modelling parameter types with optional values, and the methods must ensure that it is safe to use these. In practice, null parameters are used for much more than that. Whenever we provide a null parameter to a method, we must ensure that all of the subsequent processing of the parameter is null-safe, which can be hard. Even though it appears so, your program might be in a state that hides unsafe behavior and only during other conditions does the problem become apparent. Providing null parameters also adds a risk of introducing errors, whenever we modify any code in the downstream flow from where it is provided.

      從上一節可以得出,在呼叫帶有可選值的域建模引數型別的方法時,使用空引數是可以接受的,並且這些方法必須確保安全使用它們。 實際上,空引數的用途遠不止於此。 每當我們為方法提供空引數時,都必須確保對引數的所有後續處理都是空安全的,這可能很困難。 即使看起來像這樣,您的程式也可能處於隱藏不安全行為的狀態,並且僅在其他情況下問題才變得明顯。 每當我們從提供它的地方在下游流中修改任何程式碼時,提供空引數還增加了引入錯誤的風險。  

     

      

       

        

         

          

         

        

       

      

     

     What can be done to avoid null parameters in general?

      一般如何避免空引數?  

     Often we need to use some functionality in an existing method, but the calling context that we’re in is slightly different, and we can’t provide all the values the method calls for, or we need to provide more information than the method was initially designed for. We obviously don’t want to reimplement a virtually identical method. Code reuse is one of the pillars of maintainable code; the same functionality should not be implemented in multiple places as it introduces extra work to keep the code in sync and risk of errors. So, we modify the existing code for our purposes and use null for parameters that aren’t always provided. Some methods can by design tolerate at least some null-parameters, while others can’t. However, it can be hard to figure out which parameters are allowed to be null, and if null is even the correct value for a missing value.

      通常,我們需要在現有方法中使用某些功能,但是我們所處的呼叫上下文略有不同,並且我們無法提供該方法呼叫的所有值,或者我們需要提供比該方法更多的資訊。最初設計用於。 我們顯然不想重新實現幾乎相同的方法。 程式碼重用是可維護程式碼的Struts之一。 不應在多個地方實現相同的功能,因為它會引入額外的工作來保持程式碼同步和錯誤風險。 因此,出於我們的目的,我們修改了現有程式碼,並對並非總是提供的引數使用null。 通過設計,某些方法可以至少容忍某些空引數,而其他方法則不能。 但是,很難弄清楚哪些引數允許為空,如果空值甚至是缺失值的正確值,則很難確定。  

     In a language like Python, method signatures may contain default values for parameters that are used if an argument value is left out of a method call. However, this is not possible in Java. The closest thing is to use method overloading, where the same method signature is defined multiple times in a class with different parameters. One method will contain the full functionality and take the full set of parameters, while the others are just “decorators” for calling the method that each takes some subset of the parameters. The decorator methods define what values should be used in place in the missing parameters, so the caller won’t have to provide these. By hard-coding, which values should be provided when the caller doesn’t have all the values, we reduce the risk of errors and make the acceptable parameter values explicit.

      在Python之類的語言中,方法簽名可能包含引數的預設值,如果在方法呼叫中忽略了引數值,則使用這些引數的預設值。 但是,這在Java中是不可能的。 最接近的方法是使用方法過載 ,即在具有不同引數的類中多次定義相同的方法簽名。 一種方法將包含全部功能並採用完整的引數集,而其他方法只是用於呼叫該方法的“裝飾器”,而每種方法都採用某些引數子集。 裝飾器方法定義在丟失的引數中應使用哪些值,因此呼叫方將不必提供這些值。 通過硬編碼,當呼叫者沒有所有值時應提供哪些值,我們降低了出錯的風險,並明確了可接受的引數值。  

     You can similarly decompose constructors, but you could also use the Builder design pattern. The Builder design pattern helps to minimize constructor parameters and removes the need for passing null-values to the constructor by using a Builder object for creating your class. The gist of the pattern is that you instantiate an object indirectly through an intermediary builder class. To provide the arguments that you would have passed to the constructor directly, you call a setter corresponding to each. If a value has not been set by you, the builder will provide it instead. You then call Create() on the builder, and it instantiates the object for you. It’s a bit too complex to go into detail with here, but Refactoring.guru has a very nice article on the pattern and the trade-offs of using it. As with most patterns, it introduces extra classes and complexity, so before using it, make sure that it makes sense; using it just to avoid calling a constructor with a few null values is probably a bit overkill.

      您可以類似地分解建構函式,但也可以使用Builder設計模式 。 Builder設計模式有助於最小化建構函式引數,並通過使用Builder物件來建立類而無需將null值傳遞給建構函式。 模式的要旨是您通過中間構建器類間接例項化物件。 要提供直接傳遞給建構函式的引數,請呼叫與每個引數對應的setter。 如果您尚未設定值,那麼構建器將改為提供它。 然後,您在構建器上呼叫Create(),它將為您例項化該物件。 這裡有點複雜,但是Refactoring.guru上有一篇很好的文章介紹了模式和使用它的權衡。 與大多數模式一樣,它引入了額外的類和複雜性,因此在使用它之前,請確保它有意義。 僅使用它以避免呼叫帶有幾個null值的建構函式可能有點過頭。  

     In the solutions above, null-values are still being passed to methods internally in the object, but caller and called methods are intended to do so by design. Any method called with one of these values is expected to have proper null-handling in place. Outside callers should be prevented from providing null-values for parameters that were not considered in the design, as null-values might not be supported and proper handling is not be guaranteed.

      在上面的解決方案中,空值仍在內部傳遞給物件中的方法,但是呼叫者和被呼叫方法是設計使然的。 使用這些值之一呼叫的任何方法都應具有適當的空值處理。 應避免外部呼叫者為設計中未考慮的引數提供空值,因為可能不支援空值並且不能保證正確的處理。  

      如何思考null (How to think about null) 

     An increasing number of programming languages are starting to use a “safety on” approach to certain features. In languages like Clojure, F# and Rust variables are immutable by default; the compiler will only allow variables that are declared with a special modifier to change value. This approach to dangerous features forces programmers to override the default behavior, thereby indicating “I understand this is dangerous, I know what I’m doing and have a good reason for doing so”; doing so should not be the norm. We should think about null in the same way. We need to reserve the value for a few special cases, where it is the right thing to use, but generally, we should restrict ourselves to not use it — however, not at the cost of introducing complexity with creative workarounds. Whenever considering using null in place of a value that crosses the boundary between methods, you should take a moment to consider if you have a good reason for doing so, if you can guarantee it doesn’t end up somewhere it can cause trouble and if other developers would expect the value to be null. If not, you should reconsider the alternatives.

      越來越多的程式語言開始對某些功能使用“安全開啟”方法。 在Clojure之類的語言中,預設情況下F#和Rust變數是不可變的。 編譯器將只允許使用特殊修飾符宣告的變數來更改值。 這種危險功能的方法迫使程式設計師重寫預設行為,從而表明“我知道這很危險,我知道自己在做什麼,並且有充分的理由這樣做”; 這樣做不應該是常態。 我們應該以同樣的方式考慮null。 我們需要為一些特殊情況保留價值,在某些特殊情況下,使用它是正確的事情,但是通常,我們應該限制自己不要使用它-但是,這不以通過創造性的變通辦法引入複雜性為代價。 每當考慮使用null代替跨越方法之間邊界的值時,您都應該花一點時間考慮一下是否有這樣做的充分理由,如果可以保證它不會終止於某處會引起麻煩,以及其他開發人員希望該值為null。 如果不是,則應重新考慮替代方案。  

     Curious to know more?… “Part 2: There’s got to be a better way — modern null handling” is going live Friday 21st August 2020 on the Destination AARhus TechBlog.

      是否想知道更多?……“第2部分:必有更好的方法-現代的null處理”將於2020年8月21日(星期五)在Destination AARhus TechBlog上線。  

     By Jens Christian B. MadsenSystems Developer, Systematic

      作者:Jens Christian B. Madsen系統開發人員  

     About meJens Christian B. Madsen is a developer on the Columna clinical information system, holds master’s degrees from Aarhus University in Molecular biology and Computer Science and is a certified ethical hacker. He has contributed to books on such topics as python, computer science and Linux. He enjoys heavy books, heavy metal and heavy weights.

      關於我 Jens Christian B. Madsen是Columna臨床資訊系統的開發人員,擁有奧爾胡斯大學分子生物學和電腦科學專業的碩士學位,並且是一名經過認證的道德黑客。 他為諸如python,電腦科學和Linux等主題的書籍做出了貢獻。 他喜歡沉重的書籍,沉重的金屬和沉重的重物。  

    

   

  

 

 

  翻譯自: https://medium.com/destinationaarhus-techblog/avoiding-null-pointer-exceptions-in-a-modern-java-application-5e54fab6e3b

 

 java避免空指標異常

相關文章