Before learning and using guava optional, let's take a look at null in Java. Because, only by having a deep understanding of null, can we gain a deeper understanding of guava's optional design and usage in elegance and simplicity.
Null indicates an uncertain object:
In Java, null is a keyword used to identify an uncertain object. Therefore, null can be assigned to a reference type variable, but null cannot be assigned to a basic type variable.
In Java, the use of variables follows the principle that variables can be used only after being defined and initialized. For exampleCode, We cannot define the int age and print the age value without specifying a value for the age. This parameter is also applicable to referenced type variables (string name is also applicable), and will prompt initialization during compilation.
Public class nulltest { Public static void testnull () { int age; system. out. println ( "User age :" + age ); long money; money = 10l ; system. out. println ( "User money" + money); string name; system. out. println ( "User name:" + name) ;}
in Java, Java assigns a value to a variable by default: when defining a variable, if the variable is not assigned a value after definition, Java automatically assigns a value to the variable at runtime. The assignment principle is that the values of int, byte, short, and long are automatically assigned to 0, float and double values with decimal points are automatically assigned to 0.0, and boolean values are automatically assigned to false, variables of other reference types are automatically assigned null values. The above code is changed to the following executable code:
Public class nulltest { Public static void testnull () { int age = 0 ; system. out. println ( "user age:" + age); long money; money = 10l ; system. out. println ( "User money" + money); string name = null ; system. out. println ( "User name:" + name) ;}
Null is neither an object nor an objcet instance:
Null is just a keyword used to identify an uncertain object. It is neither an object nor an instance of an objcet object. The following code determines whether null is an object instance:
Public Class Nulltest { Public Static Void Main (string [] ARGs) {testnullobject ();} Public Static Void Testnullobject (){ If ( Null Instanceof Java. Lang. Object) {system. Out. println ( "Null belongs to the java. Lang. Object Type" );} Else {System. Out. println ( "Null does not belong to the java. Lang. Object Type" );}}}
Run the above Code and output: NULL does not belong to the java. Lang. Object type. It can be seen that the null object is not an instance of the object.
Use of null objects:
1.Common Use Cases:
Sometimes, when we define a reference type variable, we cannot give a definite value at the beginning, but do not specify a value,ProgramThe value may be initialized in the try statement block. At this time, we will report an error when using the variables below. At this time, you can first specify a null value for the variable to solve the problem. For example:
Connection conn =Null;Try{Conn= Drivermanager. getconnection ("url", "user", "password");}Catch(Sqlexception e) {e. printstacktrace ();} string catalog= Conn. getcatalog ();
If you do not specify conn = NULL at the beginning, the last sentence will return an error.
2. Container Type and null:
List: Repeated elements are allowed. You can add any number of null values.
Set: duplicate elements are not allowed. A maximum of null values can be added.
Map: A map key can be added with a maximum of null values.
Array: an array of the basic type. If the initial value is not specified after definition, the value is automatically assigned during Java runtime. Array of reference type. If no initial value is specified, all element values are null.
3. Other functions of null
1> determine whether a data of the reference type is null. Use = to judge.
2> release the memory and point a non-null reference type variable to null. In this way, this object will no longer be applied to any objects. Wait for the JVM garbage collection mechanism to recycle.
4. Suggestions for using NULL:
1>. Use null in set or map as the value to which the key value points. Never use it like this. Obviously, using null as a special example in the query operations of set and map makes the query results easier to understand.
2>. map contains key-value pairs whose values are null values. You should remove these key-value pairs from map and use an independent set to include all null or non-null keys. It is confusing whether a map contains a key whose value is null or whether such a key-Value Pair does not exist in the map. The best way is to separate these key values and think about what a key value that is null actually means for your program.
3>. Use null in the list, and the data in this list is sparse. Maybe you 'd better use a Map <integer, E> dictionary to replace this list. Because the dictionary is more efficient and may be more accurate to your subconscious needs for the program.
4>. imagine if there is a natural "null object" that can be used. For example, you can add an enumeration constant instance for the enumeration type. This instance is used to indicate the situation where you want to use the null value. For example, Java. math. roundingmode has a constant instance unnecessary to indicate "No rounding is required". If any precision calculation method is transmitted as roundingmode. when unnecessary is used as a parameter for calculation, an exception is thrown to indicate that no precision is needed.
5. Problems and confusions:
First, random use of null may cause a series of unpredictable problems. Through research and analysis on a large amount of code, we found that about 95% of the collection classes do not accept null values by default. If there is a null value, it will be put into the collection, the code will be immediately interrupted and an error will be reported instead of storing the null value by default. for development, this will make it easier to locate errors in the program.
In addition, the null value is an unpleasant fuzzy meaning. Sometimes there will be ambiguity. At this time, it is difficult to figure out the specific meaning. If the program returns a null value, what does it mean? For example: map. if the return value of get (key) is null, it indicates that the value pointed to by the key may be null, or the key does not exist in map. A null value can indicate a failure, a success, or almost any situation. Using other values (instead of null values) can make the meaning of your code clearer.
Conversely, using a null value is a correct option in some cases, because it is cheaper to use null in terms of memory consumption and efficiency, in addition, it is inevitable that null appears in the object array. However, in the program code, for example, in the function library, the use of null values will become the culprit of misunderstanding, and will also lead to some inexplicable, fuzzy, and hard-to-fix problems. As in the preceding map example, if the dictionary returns NULL, it indicates that the value pointed to by the key exists and is empty. Alternatively, it indicates that the key does not exist in the dictionary. The key is that the null value cannot indicate what the meaning of null represents.
Optional of guava:
In most cases, the programmer uses null to indicate a non-existent meaning. There may be a value, but this value is null or this value cannot be found. For example, if you use a non-existing key value to get the value from the map, the return value of map. Get is null, indicating that the map does not contain the key.
If the T type data can be null, optional <t> is a method used to replace the T type with a non-null value. An optional object can contain a non-null t reference (in this case we call it "existing") or does not contain anything (in this case we call it "vacant "). But optional never contains a reference to the null value.
ImportCom. Google. Common. Base. Optional;Public ClassOptionaltest {Public VoidTestoptional ()ThrowsException {optional<Integer> Possible = optional. Of (6);If(Possible. ispresent () {system. Out. println ("Possible ispresent:" +Possible. ispresent (); system. Out. println ("Possible value:" +Possible. Get ());}}}
For these reasons, the guava database has designed optional to solve the null problem. Many guava tools are designed to report an error immediately if a null value exists, instead of continuing to run the job as long as the context accepts the null value for processing. In addition, guava provides optional and other tools to help you avoid using NULL directly when you have to use null values.
The most common value of optional <t> is that, for example, if a method returns a data type, the code that calls this method performs the next action based on the return value of this method, if this method can return a null value indicating success or failure, it seems to be vague here, So optional <t> is used as the return value, then the subsequent code can use ispresent () to determine whether the expected value is returned (originally expected to return null or return is not null, the meaning is not clear), and you can use get () to obtain the actual return value.
Optional method description and example:
1. Common static methods:
Optional. Of (t): obtains an optional object, which contains a non-null t data type instance. If t = NULL, an error is reported immediately.
Optional. Absent (): obtains an optional object that contains a null value.
Optional. fromnullable (t): converts an instance of t to an optional object. The instance of t can be neither empty nor empty [optional. fromnullable (null), and optional. absent () is equivalent.
Example:
Import Com. Google. Common. Base. Optional; Public Class Optionaltest {@ Test Public Void Testoptional () Throws Exception {optional <Integer> Possible = optional. Of (6 ); Optional <Integer> absentopt = Optional. Absent (); optional <Integer> nullableopt = optional. fromnullable ( Null ); Optional <Integer> nonullableopt = optional. fromnullable (10); If (Possible. ispresent () {system. Out. println ( "Possible ispresent:" + Possible. ispresent (); system. Out. println ( "Possible value:" + Possible. Get ());} If (Absentopt. ispresent () {system. Out. println ( "Absentopt ispresent:" + Absentopt. ispresent ());;} If (Nullableopt. ispresent () {system. Out. println ( "Fromnullableopt ispresent:" +Nullableopt. ispresent ());;} If (Nonullableopt. ispresent () {system. Out. println ( "Nonullableopt ispresent:" + Nonullableopt. ispresent ());;}}}
2. instance method:
1>. boolean ispresent (): If the T instance in optional is not null, true is returned. If the T instance is null, false is returned.
2>. t get (): returns the T instance of optional. The T instance must not be empty. Otherwise, an illegalstateexception exception will be thrown when get () is called for the optional instance that contains null.
3>. T or (t): If the optional instance contains the same instance of input T, return the T Instance included in optional; otherwise, return the input t instance as the default value.
4>. t ornull (): return the non-empty t instance contained in optional. If optional contains a null value, null is returned, and the inverse operation is fromnullable ()
5>. set <t> asset (): returns an unchangeable set that contains all non-null t instances included in optional instances. In this set, each t instance is in a single state. If there is no non-null t instance in optional, an empty unmodifiable set is returned.
Example:
Import Java. util. Set; Import Com. Google. Common. Base. Optional; Public Class Optionaltest { Public Void Testmethodreturn () {optional <Long> value = Method (); If (Value. ispresent () = True ) {System. Out. println ( "Get return value:" + Value. Get ());} Else {System. Out. println ( "Get return value:" + value. Or (-12l );} System. Out. println ( "Get return value ornull:" + Value. ornull (); optional <Long> valuenonull = Methodnonull (); If (Valuenonull. ispresent () = True ) {Set <Long> set = Valuenonull. Asset (); system. Out. println ( "Get the size of the returned value set:" + Set. Size (); system. Out. println ( "Get return value:" + Valuenonull. Get ());} Else {System. Out. println ( "Return Value:" + valuenonull. Or (-12l );} System. Out. println ( "Get return value ornull:" + Valuenonull. ornull ());} Private Optional <long> Method (){ Return Optional. fromnullable ( Null );} Private Optional <long> Methodnonull (){ Return Optional. fromnullable (15l );}}
Output result:
Return Value:-12Returns ornull:NullObtain the size of the returned value set:1Return Value:15Returns ornull:15
Optional, in addition to improving the code readability brought about by naming null values, has the biggest advantage of optional being silly. The use of optional objects forces you to actively think about such a situation. If you want your program to return a null value, what does this null value mean, if you want to obtain the return value, you must obtain it from inside the optional object, so you must think so. However, simply using a null value can easily make you forget to think about what the meaning of the Code is. Although findbugs is helpful, however, we still think that it does not solve the problem as much as possible to help Programmers think about the meaning of the null value.
This kind of thinking is especially relevant when you return some existing values or nonexistent values. Like others, you are likely to forget the method (a, B) written by others. It may return a null value, as if you write method (a, B) you may also forget that the input parameter A can be null. If optional objects are returned, the caller can forget how to measure the meaning of null, because they always need to obtain the true return value from the optional object.