The data type

Packing type

There are eight basic types:

  • boolean/1
  • byte/8
  • char/16
  • short/16
  • int/32
  • float/32
  • long/64
  • double/64

Each basic type has a corresponding package type, and the assignment between the basic type and its corresponding package type is done using automatic packing and unpacking.

    Integer x = 2; / / packing
    int y = x;     / / split open a case
Copy the code

Buffer pool

New Integer(100) differs from integer.valueof (100) :

  • New Integer(100) creates a new object each time.
  • Integer.valueof (100) uses objects in the cache pool, and multiple calls get a reference to the same object.
    Integer x = new Integer(100);
    Integer y = new Integer(100);
    System.out.println(x == y);    // false
    Integer z = Integer.valueOf(100);
    Integer k = Integer.valueOf(100);
    System.out.println(z == k);   // true
Copy the code

The valueOf() method is simple to implement. It checks whether the value is in the cache pool and returns the contents of the cache pool if it is.

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
Copy the code

In Java 8, the default Integer cache pool size is -128 to 127.

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if(integerCacheHighPropValue ! =null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache(a) {}}Copy the code

The compiler calls the valueOf() method in the buffer-pool-scoped primitive auto-boxing procedure, so multiple Integer instances created using auto-boxing and with the same value refer to the same object.

The basic types correspond to the following buffer pools:

  • boolean values true and false
  • all byte values
  • short values between -128 and 127
  • int values between -128 and 127
  • char in the range \u0000 to \u007F

When using the wrapper types corresponding to these primitive types, objects in the buffer pool can be used directly. If out of the buffer pool:

Integer m = 320;
Integer n = 320;
System.out.println(m == n);   // false
Copy the code

String

An overview of

String is declared final, so it cannot be inherited.

Data is stored internally using a CHAR array, which is declared final, meaning that the value array cannot reference any other array once it is initialized. And there’s no way to change the value array inside a String, so it’s guaranteed to be immutable.

public final class String
    implements java.io.Serializable.Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
Copy the code

The benefits of immutability

1. You can cache hash values

Because String hash values are often used, for example String is used as the key of a HashMap. The immutable nature makes the hash value immutable, so it only needs to be evaluated once.

2. String Pool requirements

If a String object has already been created, the reference is fetched from the String Pool. String Pool can only be used if String is immutable.

3. Ensure program security

String is often used as a parameter, and String immutability ensures that the parameter is immutable. For example, if String is mutable as a network connection parameter, then during the network connection, String is changed, and the party that changed String thinks it is connected to another host, which is not necessarily the case.

4. Thread safety

The immutable nature of String is inherently thread-safe and can be used safely in multiple threads.

String, StringBuffer, StringBuilder

If the variable

  • String is immutable
  • StringBuffer and StringBuilder are mutable

Thread safety

  • String is immutable and thread-safe
  • StringBuffer, which uses synchronized internally for thread safety
  • StringBuilder threads are not safe

String.intern()

Using string.intern () ensures that String variables with the same content refer to the same memory object.

In the following example, S1 and S2 create two different objects using new String(), while S3 gets an object reference using the s1.intern() method. Intern () first puts the object referenced by S1 into the String Pool and returns the object reference. So S3 and S1 refer to objects in the same string constant pool.

String s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1 == s2);           // false
String s3 = s1.intern();
System.out.println(s1.intern() == s3);  // true
Copy the code

If you create String instances using double quotes like “BBB”, the new object is automatically placed in the String Pool.

String s4 = "bbb";
String s5 = "bbb";
System.out.println(s4 == s5);  // true
Copy the code

Prior to Java 7, the string constant pool was placed in the runtime constant pool, which belongs to the persistent generation. In Java 7, the string constant pool was moved to Native Methods. This is because the space of the permanent generation is limited, resulting in OutofMemoryErrors in scenarios where large numbers of strings are used.

operation

Parameter passing

Java parameters are passed to methods as values, not references.

When you pass a parameter to a method, you are essentially passing the object’s address to the parameter as a value.

Float and double

1.1 literals are of type double. You cannot assign 1.1 directly to a float variable because this is a downward transition. Java cannot implicitly perform a downward transformation because it would reduce accuracy.

A 1.1F literal is a float.

Implicit type conversion

Because the literal 1 is an int, it is more precise than short, so we cannot implicitly cast int to short. s1 = s1 + 1; A compilation error is reported, but implicit type conversions can be performed using the += operator. s1 += 1; Equivalent to the downward transformation of s1 + 1: S1 = (short) (S1 + 1);

switch

Starting with Java 7, you can use strings in switch conditional statements.

String s = "a";
switch (s) {
    case "a":
        System.out.println("aaa");
        break;
    case "b":
        System.out.println("bbb");
        break;
}
Copy the code

The switch does not support long because it is designed to perform equivalence judgments on only a small number of values. If the values are too complex, use if instead.

inheritance

Access permissions

There are three access modifiers in Java: private, protected, and public. Without access modifiers, this means package-level visibility.

You can add access modifiers to a class or its members (fields and methods).

  • Class visibility means that other classes can use this class to create instance objects.
  • Member visibility means that other classes can access the member using the instance object of the class.

Protected is used to modify members, meaning that in inheritance the member is visible to subclasses, but the access modifier has no meaning for the class.

A well-designed module hides all implementation details, clearly separating its API from its implementation. Modules communicate with each other only through their apis, and one module does not need to know the inner workings of other modules, a concept known as information hiding or encapsulation. So access permissions should be kept as close as possible to each class or member.

If a method of a subclass overrides a method of the parent class, the access level of that method in the subclass is not allowed to be lower than that of the parent class. This is to ensure that subclass instances can be used wherever parent instances can be used, which is to ensure that the Richter substitution principle is met.

Fields should never be public, because to do so would lose control over how the field is modified, and the client can modify it at will.

Abstract classes and interfaces

1. An abstract class

Both abstract classes and abstract methods are declared using the abstract keyword. Abstract classes typically contain abstract methods, which must reside in the abstract class.

The biggest difference between an abstract class and a normal class is that an abstract class cannot be instantiated. It must inherit from the abstract class to instantiate its subclasses.

2. The interface

An interface is an extension of an abstract class. Prior to Java 8, it could be considered a completely abstract class, meaning that it could not have any method implementation.

Starting with Java 8, interfaces can also have default method implementations, because interfaces that do not support default methods are too expensive to maintain. Prior to Java 8, if an interface wanted to add new methods, it changed all the classes that implemented the interface.

Interface members (fields + methods) are public by default and are not allowed to be private or protected.

Interface fields are static and final by default.

3. Compare

  • From A design point of view, abstract classes provide an IS-A relationship that must satisfy the In-class substitution principle, i.e. subclass objects must be able to replace all superclass objects. An interface, on the other hand, IS more LIKE A like-a relationship. It simply provides A way to implement the contract and does not require the interface to have an IS-A relationship with the class implementing the interface.
  • In terms of usage, a class can implement multiple interfaces, but cannot inherit multiple abstract classes.
  • Fields of an interface can only be static and final; fields of an abstract class have no such restriction.
  • Members of an interface can only be public, whereas members of an abstract class can have multiple access rights.

Used to choose

Use interface:

  • The compareTo() method of the Compareable interface can be implemented by all unrelated classes.
  • Multiple inheritance is required.

Using abstract classes:

  • You need to share code in several related classes.
  • You need to be able to control the access of inherited members, not all of them public.
  • You need to inherit non-static and nonstatic fields.

In many cases, interfaces take precedence over abstract classes because they do not have the strict class hierarchy requirements of abstract classes and can flexibly add behavior to a class. And starting with Java 8, interfaces can also be implemented with default methods, making it much cheaper to modify interfaces.

super

  • Access the constructor of the parent class: You can use the super() function to access the constructor of the parent class, thereby delegating some initialization to the parent class.
  • Accessing a member of a parent class: If a subclass overrides the implementation of a method in the parent class, it can refer to the method implementation of the parent class by using the super keyword.

Rewriting and overloading

1. Rewrite (Override)

In inheritance, a subclass that implements a method that is identical in method declarations to its parent class.

In order to satisfy the li substitution principle, rewriting has the following two limitations:

  • Subclass methods must have access greater than or equal to the parent method;
  • The return type of a subclass method must be the parent method return type or a subtype. Using the @Override annotation, you can have the compiler check to see if the above two restrictions are met.

2. Overloaded (phrase)

A method that exists in the same class has the same name as an existing method but has at least one different parameter type, number, and order.

It should be noted that if the return value is different and everything else is the same it’s not an overload.

Object general method

equals()

1. Equivalence relation

(1) reflexivity

x.equals(x); // true

Copy the code

2. Symmetry

x.equals(y) == y.equals(x); // true

Copy the code

(3) transitivity

if (x.equals(y) && y.equals(z)) {
    x.equals(z); // true;
}

Copy the code

(4) consistency

Calls to equals() will not change

x.equals(y) == y.equals(x); // true

Copy the code

(5) Comparison with NULL

Calling x. als(null) on any object x that is not null results in false

x.equals(null); // false;

Copy the code

2. The equals () and = =

  • For base types, == determines whether two values are equal. Base types have no equals() method.
  • For reference types, == determines whether two variables refer to the same object, and equals() determines whether the referenced objects are equivalent.

The keyword

final

1. Data

Declare data as constants, either at compile time or after initialization at run time that cannot be changed.

  • For basic types, final leaves the value unchanged;
  • For reference types, final leaves the reference unchanged and therefore cannot refer to other objects, but the referenced object itself can be modified.

Method 2.

Declaration methods cannot be overridden by subclasses.

Private methods are implicitly specified as final. If a method defined ina subclass has the same signature as a private method in the base class, the subclass’s method does not override the base class method, but defines a new method in the subclass.

Class 3.

Declare that classes are not allowed to be inherited

static

Static variables

  • Static variable: Also known as a class variable, that is, the variable belongs to the class. All instances of the class share a static variable and can access it directly through the class name. Only one copy of a static variable exists in memory.
  • Instance variables: An instance variable is created for each instance that is created, and it lives and dies with that instance.

2. Static methods

Static methods exist when the class is loaded and do not depend on any instance. So a static method must have an implementation, that is, it cannot be an abstract method.

Only static fields and methods of the owning class can be accessed. Methods cannot have the this and super keywords.

Static statement blocks

A static statement block is run once during class initialization.

Static inner classes

Non-static inner classes depend on instances of external classes, whereas static inner classes do not.

A static inner class cannot access the non-static variables and methods of an external class.

5. Static packet guide

When using static variables and methods, you no longer have to specify a ClassName, simplifying the code but greatly reducing readability.

6. Initialization sequence

Static variables and static statement blocks take precedence over instance variables and normal statement blocks, and the order in which they are initialized depends on the order in which they are placed in the code. Finally, the constructor is initialized.

In the case of inheritance, the initialization sequence is:

  • Parent class (static variables, static statement blocks)
  • Subclasses (static variables, static statement blocks)
  • Parent classes (instance variables, plain statement blocks)
  • Parent class (constructor)
  • Subclasses (instance variables, plain statement blocks)
  • Subclass (constructor)

reflection

Each Class has a Class object that contains information about the Class. When a new class is compiled, a.class file of the same name is generated, the contents of which hold the class object.

Class loading is equivalent to the loading of Class objects. Classes are dynamically loaded into the JVM the first time they are used. You can control Class loading by using class.forname (” com.mysql.jdbc.driver “), which returns a Class object.

Reflection can provide information about a class at run time, and the class can be loaded at run time, even if its.class does not exist at compile time.

Class provides support for reflection along with java.lang.reflect. The Java.lang. Reflect library consists of three classes:

  • Field: You can use the get() and set() methods to read and modify the fields associated with the Field object;
  • Method: You can use the invoke() Method to call a Method associated with a Method object;
  • Constructor: Use Constructor to create new objects.

abnormal