A wrapper class
1. Why is the wrapper class needed?
Java was designed with a basic principle: everything is an object, and all operations need to be described in object form. But there is a paradox here. The basic data type is not an object. So how do we fix this BUG? The simplest way to do this is to store the base data type as a class property, which is equivalent to wrapping the base data type.
A wrapper class that implements the basic data types
package com.shxt.demo01;
public class Int {/ / class
private int number;// Basic data type
public Int(int number){// Provide a constructor for a parameter, passing in the basic data type
this.number = number;
}
public int intValue(a){// Get the data in the wrapper class
return this.number;
}
// Other methods can be provided
}
Copy the code
package com.shxt.demo01;
public class MyTest {
public static void main(String[] args) {
Int temp = new Int(100); // Wrap the basic data type into a class
int result = temp.intValue(); // Get the basic data type from the classSystem.out.println(result+result); }}Copy the code
Code analysis:
We have implemented the way in which primitive data types are converted to Java objects, and Java provides us with similar implementation classes
Package form
Basic data types | A wrapper class |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
Int ->Integer,char->Character, char->Character, char->Character
However, the packaging category given above can be divided into two types:
- Object wrapper classes: Character, Boolean.
- Numeric wrapper classes (direct subclasses of Number) : Byte, Short, Integer, Float, Double, Long.
Number is an abstract class that defines six operation methods: intValue(), shortValue(), byteValue(), floatValue(), longValue(), doubleValue().
2. Packing and unpacking
Now that there are primitive data types and wrapper classes, the conversion between these two variables is defined in the following way.
- Boxing operation: Changes the base data type into the form of a wrapper class.
- Each wrapper class constructor can accept variables of its own data type.
- Unpacking operation: take out the packaged data from the packaged class.
- Do this using a series of: xxxValue() methods provided in the Number class.
Example 1- Use int and Integer as examples to illustrate the process of packing and unpacking operations
public class Demo01 {
public static void main(String args[]) {
Integer obj = new Integer(10); // Box the basic data types
int temp = obj.intValue(); // Unpack the basic data types
System.out.println(temp * 2); // The result is 20}}Copy the code
Instead of using the Int class I wrote, I’m using the Integer system class.
Example 2- Use a double and a double to illustrate the process of boxing and unboxing
public class Demo02 {
public static void main(String args[]) {
Double obj = new Double(10.2); // Box the basic data types
double temp = obj.double Value(a); // Unpack the basic data types
System.out.println(temp * 2); // The result is 20.4}}Copy the code
Example 3- Demonstrates the process of boxing and unboxing using Boolean and Boolean as examples (not the Number subclass)
public class Demo03 {
public static void main(String args[]) {
Boolean obj = new Boolean(false); // Box the basic data types
boolean temp = obj.booleanValue(); // Unpack the basic data types
System.out.println(temp); // The result is false}}Copy the code
You can now see that all wrapper classes operate using the same form of method. Prior to JDK1.5, all operations were in the above form of code, but after JDK1.5, Java provided automatic boxing and automatic unboxing for ease of development, and can directly use the objects of the wrapper class to perform mathematical calculations.
Example 4- Observe the automatic packing and unpacking operations using INT and Integer as examples
public class Demo04 {
public static void main(String args[]) {
Integer obj = 10; // Automatic boxing int->Integer
int temp = obj; // Automatic unboxing Integer->int actually calls obj.intValue()
obj ++;
System.out.println(temp * obj); // The result is 110}}Copy the code
Example 5- Observe the process of automatic boxing and automatic unboxing using Boolean and Boolean as examples (not the Number subclass)
public class Demo05 {
public static void main(String args[]) {
Boolean obj = false; // Automatic boxing Boolean ->Boolean
boolean flag = obj; Boolean-> Boolean
if(! flag){ System.out.println(Boolean is not a subclass of Number); }}}Copy the code
Since Java provides automatic boxing and unboxing, Object can accept all data types.
Conversion process: Basic data types → automatic boxing (to become objects) → upward transformation to Object.
Example 6- Receiving the int data type as Object demonstrates the conversion process
public class Demo06 {
public static void main(String args[]) {
Object obj = 10; // int->Integer(automatically boxing as an Object)->Object
int temp = (Integer)obj; // Object->Integer(cast to wrapper class)-> Automatic unboxing
obj ++;
System.out.println(temp * obj); // The result is 110}}Copy the code
NullPointException for “no reason”
During our development, we encountered a number of NullPointExceptions caused by request parameters or interface definition fields being set to int (or some other primitive type). The code runs roughly as follows, but not exactly as this.
public class Demo06 {
public static void main(String args[]) {
Integer a = null;
int b = a; // Throw NullPointException a.intValue();}}Copy the code
Code analysis:
The above code compiles, but throws a NullPointException.
Int b = a int b = a.int value ()
Since a’s reference value is NULL, calling a method on an empty object throws a NullPointException.
3. = = and equlas ()
You should know the difference between the two,
Equlas () compares values. Values of the same basic type refer to the same block of memory, so they can be compared with ==. Reference types do not.
public class Demo07 {
public static void main(String args[]) {
Integer obja = 10; // Assign directly
Integer objb = 10; // Assign directly
Integer objc = new Integer(10); // constructor
System.out.println(obja == objb); // true does not compare memory addresses. Why is that?
System.out.println(obja == objc); // false
System.out.println(objb == objc); // false
System.out.println(obja.equals(objc)); // true}}Copy the code
Code analysis:
Isn’t obja == objb supposed to compare memory addresses? Why is it equal? We need to solve this problem, source code analysis
This is rarely done using constructors when using wrapped classes, and is almost always done directly (as with strings), but remember to use equals() whenever content is equal.
Two wrapper classes reference equality
In Java, the “==” symbol determines the equivalence of a memory address. Specifically, primitive types determine whether values are equal, and reference types determine whether the address they point to is equal. Take a look at the following code, two similar code logic, but get completely different results.
public class Demo08 {
public static void main(String args[]) {
Integer a1 = 127;
Integer a2 = 127;
System.out.println(a1 == a2); // true
Integer b1 = 128;
Integer b2 = 128;
System.out.println(b1 == b2); // false}}Copy the code
The answer to this must be found in the source code. The source code for the valueOf() method in the Integer class is as follows:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) // Check whether the argument is in the cacheable range. Default is [-128, 127].
return IntegerCache.cache[i + (-IntegerCache.low)]; // If so, fetch the initialized Integer object
return new Integer(i); // If not, a new Integer object is created
}
Copy the code
Code analysis:
Because 127 is in the range of [-128, 127], valueOf() will fetch the same Integer object every time, so the first “==” evaluates to true. 128 does not belong to [-128, 127], so valueOf() creates a new Integer object each time. Because the addresses of the two newly created objects are different, the result of the first “==” is false.
Analyze the comparison process again
package com.shxt.demo01;
public class MyTest {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println(c==d); // Cache mechanism, return true
System.out.println(e==f); // The cache mechanism is exceeded and the return value is false
// (a+b) calculates that the automatic unpacking becomes an int, and c requires the automatic unpacking to become an int
System.out.println(c==(a+b));
//(a+b) evaluates automatic unboxing to int because equals compares content (a+b) with automatic boxing and returns true
System.out.println(c.equals(a+b));
// (a+b) evaluates to int, g to long, and (a+b) returns true
System.out.println(g==(a+b));
//(a+b) calculates auto unboxing to int because equals compares content (a+b) to auto unboxing Integer
// Compare Long with Integer, return false
System.out.println(g.equals(a+b));
Return true for automatic type conversionSystem.out.println(g.equals(a+h)); }}Copy the code
4. Data type conversion (core)
The most common use of the wrapper class is actually its data type conversion function, in the wrapper class, the biggest advantage is to provide String data into the basic data type method, using several representative classes to illustrate:
- Integer class :public static int parseInt(String s)
- Public static Double parseDouble(String s)
- Public static Boolean parseBoolean(String s).
The **Character class does not have a method that converts a String to a Character, because the String class has a charAt() method that fetches the Character content by index, and a Character is only one bit long.
Example 1: Turn a string into an int
public class Demo01 {
public static void main(String args[]) {
String str = "123"; / / string
int temp = Integer.parseInt(str);//String->int
System.out.println(temp * 2); }}Copy the code
At this point, the string becomes a primitive data type. However, it is important to note that the string to be converted to a number must consist of numbers. If it is not a number, a NumberFormatException is raised during conversion
Example 2: Error code
public class Demo02 {
public static void main(String args[]) {
String str = "1sss3"; / / string
int temp = Integer.parseInt(str);
System.out.println(temp * 2); }}Copy the code
Exception in thread "main" java.lang.NumberFormatException:For input string:"1sss3"
Copy the code
Example 3: Turn a string into a double
public class Demo03 {
public static void main(String args[]) {
String str = "13"; / / string
double temp = Double.parseDouble(str);
System.out.println(temp * 2); // Output 26.0}}Copy the code
Example 4: Change a string to Boolean data
public class Demo04 {
public static void main(String args[]) {
String str = "true"; / / string
boolean flag = Boolean.parseBoolean(str);
if(flag) {
System.out.println("Satisfied!");
} else {
System.out.println("Condition not met!"); }}}// Console output: the condition is met
Copy the code
Example 5: Change a string to Boolean data
public class Demo05 {
public static void main(String args[]) {
String str = "hanpang"; // Error string
boolean flag = Boolean.parseBoolean(str);
if(flag) {
System.out.println("Satisfied!");
} else {
System.out.println("Condition not met!"); }}}// Console output: does not meet the condition!
Copy the code
Code analysis:
When Boolean is converted, if the string to be converted is not true or false, it is treated as false.
Now that we have implemented a string to primitive, we must be able to implement a string to primitive. There are two ways to do this:
-
Operation 1: Any basic data type and string is indicated as a string after the + operation is used.
public class Demo06 { public static void main(String args[]) { int num = 100; String str = num + ""; / / into a String System.out.println(str.replaceAll("0"."9")); }}// Console output: 199 Copy the code
Although such operations can be easily completed, there will be garbage problems.
-
Public static String valueOf public static String valueOf
public class Demo07 { public static void main(String args[]) { int num = 100; String str = String.valueOf(num); / / into a String System.out.println(str.replaceAll("0"."9")); }}Copy the code
Such transformations do not generate garbage, so they are often used during development.
5. Summary
- Make sure that JDK1.5 provides automatic packing and unpacking operations.
- Conversions between strings and primitive data types:
- The string becomes a primitive data type, depending on the parseXxx() method of the wrapper class.
- The base data type becomes a String, using the string.valueof (data type variable) method.