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

參考鏈接: 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避免空指針異常

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540249.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540249.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540249.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[轉載] 什么是Java中的自動拆裝箱 integer

參考鏈接: Java中autoboxing自動裝箱整數對象的比較 本文主要介紹Java中的自動拆箱與自動裝箱的有關知識。 1、基本數據類型 基本類型,或者叫做內置類型,是Java中不同于類(Class)的特殊類型。它們是我們編程中使用最頻繁的類型。 Jav…

[轉載] python常用庫

參考鏈接: Python–新一代語言 轉載至:https://www.cnblogs.com/jiangchunsheng/p/9275881.html 今天我將介紹20個屬于我常用工具的Python庫,我相信你看完之后也會覺得離不開它們。他們是: Requests.Kenneth Reitz寫的最富盛…

linux下安裝配置oracle

檢查系統是否已安裝所需的開發包 使用rpm -qa命令,確保以下包已成功安裝。對于包的版本,只有版本高于下面的都可以,如果低于此版本,則要升級處理,如下: binutils-2.15.92.0.2-13.EL4 compat-db-4.1.25-9 compat-libstdc-296-2.96-132.7.2 control-center-2.8.0-12 g…

[轉載] c++多態與java多態性_Java中的多態性

參考鏈接: Java中的加法和串聯 c多態與java多態性 Polymorphism is one of the core concepts of OOPS paradigm. The meaning of polymorphism is the condition of occurring in several different forms. 多態是OOPS范式的核心概念之一。 多態性的含義是以幾種不…

USB peripherals can turn against their users

Turning USB peripherals into BadUSB USB devices are connected to – and in many cases even built into – virtually all computers. The interface standard conquered the world over the past two decades thanks to its versatility: Almost any computer peripheral…

[轉載] JAVA條件表達式的陷阱

參考鏈接&#xff1a; Java條件表達式中的數字類型提升 Map<String, Integer> map new HashMap<String, Integer>(); map.put("count", null); Integer it map null ? 0 : map.get("count"); 注意&#xff1a;在第三行&#xff0c;會…

Linux系統管理初步(七)系統服務管理、chkconfig與systemd 編輯中

Linux系統本身包含了很多服務&#xff0c;CentOS6之前系統的服務用SysV控制&#xff0c;CentOS7改為systemd控制 一、chkconfig服務管理機制 簡而言之&#xff0c;chkconfig就是CentOS6以前用來控制系統服務的工具&#xff0c; 常用方法舉例 chkconfig --list #列出所有的系統服…

[轉載] 菜鳥舉例理解字節流和字符流區別

參考鏈接&#xff1a; Java中的字符流與字節流 Character Stream對比Byte Stream 菜鳥舉例理解字節流和字符流區別 按照uft8編碼方式存儲文檔 文檔存儲路徑在D盤下 /** * 按照utf8格式存儲文檔 */ public static void storeDataByUTF8(){ String path "D:" …

[轉載] Java9發布回顧Java 8的十大新特性

參考鏈接&#xff1a; Java中的DoubleStream mapToObj() java9已經在北京時間9月22日正式發布&#xff0c;開發者可以在oracle jdk官網上下載到最新的jdk9。 今天&#xff0c;我們先來一起復習一下2014年發布的Java 8的十大新特性。先來喝杯java~~~ 按照java升級的傳統&…

窗體間傳遞數據

前言 做項目的時候&#xff0c;winfrom因為沒有B/S的緩存機制&#xff0c;窗體間傳遞數據沒有B/S頁面傳遞數據那么方便&#xff0c;今天我們就說下winfrom中窗體傳值的幾種方式。 共有字段傳遞 共有字段傳遞實現起來很方便&#xff0c;就是在窗體類中加個共有字段屬性&#xff…

[轉載] c語言中檢查命令行參數_C中的命令行參數

參考鏈接&#xff1a; Java中的命令行參數 c語言中檢查命令行參數 Command line argument is a parameter supplied to the program when it is invoked. Command line argument is an important concept in C programming. It is mostly used when you need to control your …

MySQL關閉Enterprise Server源碼

今天從MySQL官方網站上獲知&#xff0c;MySQL宣布關閉Enterprise Server的源碼&#xff0c;對于廣大開源愛好者來說&#xff0c;這是一個沉重的打擊。雖然免費的用戶群體一般僅僅使用MySQL Community Server&#xff08;開源免費社區版&#xff09;&#xff0c;但關閉MySQL Ent…

[轉載] Java中Scanner用法總結

參考鏈接&#xff1a; Java之Scanner類 最近在做OJ類問題的時候&#xff0c;經常由于Scanner的使用造成一些細節問題導致程序不通過&#xff08;最慘的就是網易筆試&#xff0c;由于sc死循環了也沒發現&#xff0c;導致AC代碼也不能通過。。。&#xff09;&#xff0c;因此對S…

os和shutil模塊

import os //os模塊基本實現了linux系統中所有的命令 os.system(終端命令)&#xff1a;在終端執行命令 os.getcwd():獲取當前的工作路徑 os.chdir():修改工作路徑 os.chmod():修改權限 os.chown():修改屬主屬組 os.mkdir():創建單個目錄&#xff0c;當目錄存在時報異常&…

[轉載] JAVA語言程序設計(基礎篇)第十版課后題答案(第一章)

參考鏈接&#xff1a; Java中的Scanner和nextChar() JAVA語言程序設計&#xff08;基礎篇&#xff09;第十版課后題答案 第一章 第二題 /** Created by ysy on 2018/7/6. */ public class text2 { public static void main(String[] args){ for(int i 0; i < 5; i) Syste…

java.util.Date和java.sql.Date 一點區別

最近無意中發現&#xff0c;在oracle中同一樣的一個Date類型字段&#xff0c;存儲的日期格式有兩種不同的情況&#xff0c;第一種是2011-1-1 12:00:00&#xff0c;第二種是2011-1-1&#xff0c;仔細查找發現在向數據庫中寫數據的時候定義的變量的問題。 第一種是&#xff1a;ja…

[轉載] java中關于用\t格式輸出

參考鏈接&#xff1a; 用Java格式化輸出 看了好多人關于\t的用法&#xff0c;感覺找不到自己想要的答案&#xff0c;所以索性就自己輸出來看看&#xff0c;如圖&#xff1a;這樣可以一目了然的看出來&#xff0c;\t&#xff08;制表符&#xff09;的作用就是看前面輸出滿不滿8…

微信搶房軟件開發

2019獨角獸企業重金招聘Python工程師標準>>> 這兩年樓市真可謂是一個"火“字難以形容 經歷了長沙兩次開盤&#xff0c;都沒有搶到&#xff0c;目前還沒有買到房子&#xff0c;說說我的悲劇吧&#xff0c;讓大伙都開心開心 第一次搶房是今年4月份長沙萬科金域國…

[轉載] Java——數組習題

參考鏈接&#xff1a; Java從控制臺讀取輸入的方法 package chap02; import java.util.Scanner; /** * * author admin * date 2020-4-8 * description: * 題目內容&#xff1a; 編寫程序&#xff0c; 從控制臺讀取下面的信息&#xff0c; 每月按22天工作日計算&#xff0c;…

超全Linux備份工具集合,滿足你的所有需要!

經常備份計算機上的數據是個好的做法&#xff0c;它可以手動完成&#xff0c;也可以設置成自動執行。許多備份工具擁有不同的功能特性&#xff0c;讓用戶可以配置備份類型、備份時間、備份對象、將備份活動記入日志及執行更多操作。 1.Rsync這是一款在Linux用戶當中頗受歡迎的命…