Some of this article borrows from JavaGuide

From the author’s personal point of view, in view of the Java foundation of some rare and difficult points for sorting out, I hope to help the brothers in need

1 keyword

1.1 private

All private methods ina class are implicitly specified as final

1.2 the static

Static modified variables are never serialized

Static modified content in a class is recommended to be called by the class name

Import static Import static members that can be used directly without using the class name

1.3 strictfp

Strictfp keywords can be applied to methods/classes/interfaces, not abstract methods/variables/constructors, ensuring the same results on each platform

It is often used for floating point number related content to prevent data accuracy inconsistency caused by different platforms

This keyword has been removed from Java 17, which addresses floating-point instructions

1.4 transient

For variables that you do not want to serialize, use TRANSIENT

Note the following:

  • You can only modify variables, not classes and methods
  • Modified variable,The variable value will be set to the default value of the type after deserialization.For example, if it is a modifierintType, so the result of deserialization is0

2 Basic Types

2.1 Introduction to the eight Basic Types

Basic types of digits byte The default value
int 32 4 0
short 16 2 0
long 64 8 0L
byte 8 1 0
char 16 2 ‘u0000’
float 32 4 0f
double 64 8 0d
boolean 1 false

Boolean, which depends on the JVM vendor’s implementation, is theoretically 1 bit and may vary

2.2 Accuracy loss

Both floats and doubles lose precision because converting data to binary can loop indefinitely beyond its storage length

When dealing with extremely sensitive floating point data such as amounts, use BigDecimal to handle operations

When creating BigDecimal, use either the string argument or the valueOf method:

// YES!!
new BigDecimal("0.1");
BigDecimal.valueOf(0.1 f);
// NO!! You lose accuracy
new BigDecimal(0.1 f);
Copy the code

2.3 Type of Packaging

Primitive types have corresponding wrapper types, which exist to allow null value meanings

For example, if a student took an exam and got a score of 0 and did not take an exam and got a score of NULL, the basic int type is not reflected, but its wrapper type Integer is

Wrapper types have constant pools except Float and Double, so use equals instead of == when comparing:

// There is an Integer object with a value of 1 in the constant pool
Integer i1 = 1;
Integer i2 = 1;
Integer i3 = new Integer(1);
// Result is true
i1 == i2;
// The result is false
i1 == i3;
// Result is true
i1.equals(i3);
Copy the code

3 function

3.1 Function Signature

A function signature is the unique identification of a function in a class

The content includes the method name/parameter type/parameter name, not the return value

3.2 overloading

To occur in the same class (or between a parent class and a subclass), the method name must be the same, the argument type must be different/the number of arguments must be different/the order of arguments must be different, and the method return value and access modifier can be different

Can there be overloads with same method name/same parameter but different return value?

The answer is no, function signatures in 3.1 do not include return values, so methods with the same name/argument but different return values are considered the same method and cannot be overridden

3.3 rewrite

The method name/argument list must be the same, the exception range thrown must be less than or equal to the parent class, and the access modifier range must be greater than or equal to the parent class

If the method’s return value type is void and primitive, the return value cannot be modified when overwritten

If a method’s return value type is a reference type, overrides can return a subclass of that reference type

3.4 try-catch – finally

When there is a return in both a try statement and a finally statement, the return value of the finally statement overrides the original return value

In other words, finally statements must be executed

// return 0
try {
    return 1;
} catch (Exception e) {
    // ...
} finally {
    return 0;
}
Copy the code

3.5 the try – with – the resource

This applies to any object that implements java.lang.AutoCloseable or java.io.Closeable, and the close method is automatically called

4 Object Oriented

4.1 Object Construction sequence

  1. Static code block
  2. Non-static code blocks
  3. A constructor

4.2 Static code blocks

public class Person {

    static {
        // Static code block}}Copy the code

Static code is executed only once in the class initialization step, written in the code as follows:

  • new Person()
  • Class.forName("cn.houtaroy.models.Person")

Here’s a concrete example:

package cn.houtaroy.models;

public class Person {

    static {
        System.out.println("Static code block execution");
    }
    
    public static void main(String[] args) {
        try {
            new Person();
            Class.forName("cn.houtaroy.models.Person");
            new Person();
        } catch(Exception e) { e.printStackTrace(); }}}Copy the code

The above code has only one output: static code block execution

Static code blocks define initialization content that is common to different objects

There can be multiple blocks of static code in a class, executed in the order in which they appear

public class Person {

    static {
        / / perform first
    }
    static {
        / / perform again}}Copy the code

Static code blocks Can be assigned to static variables defined after it, but cannot be accessed:

public class Person {

    static {
        // Can be assigned
        age = 0;
        // IDE error, cannot access
        System.out.printf("Age of birth: % D", age);
    }
    
    public static Integer age;
    
}
Copy the code

4.3 Static inner Classes

  1. There is no need to rely on the creation of peripheral classes
  2. You cannot use non-static member variables and methods of any enclosing class

Static inner classes can be used to implement the singleton pattern with the benefits of lazy initialization and thread-safety support provided by the JVM:

public class PersonFactory {

    // Private constructor to prevent external calls
    private PersonFactory(a) {}// Private static inner class that cannot be accessed externally
    private static class PersonFactoryHolder {
        private static final PersonFactory INSTANCE = new PersonFactory();
    }

    // Static method that calls a private static inner class to get a unique instance
    public static PersonFactory getInstance(a) {
        returnPersonFactoryHolder.INSTANCE; }}Copy the code

4.4 hashCodewithequals

HashCode is used to determine whether objects have the same hash value

Equals is used to determine whether objects are the same

HashCode and equals are used wherever hash is used, such as HashMap. So when overwriting, make sure the results are the same

4.5 value transfer

There is only value passing in Java, even in object orientation. Here’s a concrete example:

public class Test {

    public static void main(String[] args) {
        Student s1 = new Student("Zhang");
        Student s2 = new Student("Xiao li");
        Test.swap(s1, s2);
        System.out.println("s1:" + s1.getName());
        System.out.println("s2:" + s2.getName());
    }

    public static void swap(Student x, Student y) {
        Student temp = x;
        x = y;
        y = temp;
        System.out.println("x:" + x.getName());
        System.out.println("y:"+ y.getName()); }}Copy the code

The output is:

X: Xiao Li Y: Xiao Zhang S1: Xiao Zhang S2: Xiao LiCopy the code

You can see that inside the function x and y are swapped, but outside s1 and s2 are not changed

So the four variables represent the following meanings:

  • s1: The value referenced by the student zhang object
  • s2: student li object reference value
  • x: deep copy of s1
  • y: deep copy of S2

Because x and y are deep copies, so whatever happens to them doesn’t affect s1 and S2, right

4.6 this/superWith static

The two have completely different conceptual categories:

  • Static methods are the concept of class categories
  • this/superIs the concept of object category

4.7 Objects.equals

Objects.equals is recommended for comparison (not classes, but all) :

// Both are false, and null pointer exceptions are not thrown
Objects.equals("Houtaroy".null);
Objects.equals(null."Houtaroy");
Copy the code

5 the enumeration

5.1 Using enumeration related collections

When using enumerations as elements, key values, etc., it is recommended to use enumer-dependent collections such as EnumSet and EnumMap:

/ / created enumsets
EnumSet<Gender> set = EnumSet.of(Gender.MAN);
/ / create EnumMap
EnumMap<Gender, String> map = new EnumMap<>(Gender.class);
map.put(Gender.MAN, "Man");
Copy the code

5.2 Implement the design pattern

The singleton pattern

Using enumerations allows a more concise/efficient/secure implementation of the singleton pattern, and is guaranteed by the JVM

public enum PersonFactory {

    INSTANCE;

    PersonFactory() {
      // Implement the staff factory initialization
      person = PersonCheckEntity.builder().id("test").build();
    }

    private PersonCheckEntity person;

    public static PersonFactory getInstance(a) {
      return INSTANCE;
    }

    public PersonCheckEntity getDeliveryStrategy(a) {
      return this.person; }}Copy the code

The strategy pattern

public enum PersonStrategy {

    STAND {
        @Override
        public void advance(Person person) {
            System.out.println("One step forward.");
        }
    },
    SIT {
        @Override
        public void advance(Person person) {
            System.out.println("Climbed forward a little bit."); }};public abstract void advance(Person person);
    
}

public class Person {
    
    private PersonStrategy status;
    
    public void advance(a) {
        status.advance(this); }}Copy the code

The state pattern

public enum PersonStrategy {

    STAND {
        @Override
        public void walk(Person person) {
            System.out.println("One step forward.");
        }
    },
    SIT {
        @Override
        public void walk(Person person) {
            System.out.println("Can't walk sitting down. Stand up."); person.setStatus(PersonStrategy.STAND); person.walk(); }};public abstract void walk(Person person);
    
}

public class Person {
    
    private PersonStrategy status;
    
    public void walk(a) {
        status.walk(this); }}Copy the code

6 reflection

6.1 What is Reflection

Reflection is the soul of the frame

It gives the program the ability to analyze and use class concepts in the process of running, so that we break away from the most basic business logic, and stand in a higher dimension to deal with and think about problems

Sharp-tool annotations in Java use reflection

6.2 getClassObject in four ways

A Class object can be understood as a description of a Class

A concrete class

Class myClass = Target.class;
Copy the code

Class.forName

Class myClass = Class.forName("cn.houtaroy.models.Target");
Copy the code

Object instance

Target object = new Target();
Class myClass = object.getClass();
Copy the code

Class loader

Class myClass = ClassLoader.loadClass("cn.houtaroy.models.Target");
Copy the code

Classes obtained through the classloader are not initialized, meaning that static blocks and objects are not executed without a series of steps including initialization

6.3 Specific Operations

Create target class:

public class Target {

    private String value;

    public void say(String name) {
        System.out.printf("I love %s%n", name);
    }

    private void classValue(a) {
        System.out.printf("value is %s%n", value); }}Copy the code

To perform reflection operations:

public class ExampleUtils {
    
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
        NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class<? > targetClass = Class.forName("cn.houtaroy.models.Target");
        Object targetObject = targetClass.newInstance();
        Method[] methods = targetClass.getMethods();
        for (Method method : methods) {
            System.out.printf("Owning method: %s%n", method.getName());
        }
        Field[] fields = targetClass.getFields();
        for (Field field : fields) {
            System.out.printf("Have field: %s%n", field.getName());
        }
        targetClass.getDeclaredMethod("say", String.class).invoke(targetObject, "Java");
        Field valueField = targetClass.getDeclaredField("value");
        valueField.setAccessible(true);
        valueField.set(targetObject, "test");
        Method classValueMethod = targetClass.getDeclaredMethod("classValue");
        classValueMethod.setAccessible(true); classValueMethod.invoke(targetObject); }}Copy the code

The running results are as follows:

Owning methods: say owning methods: wait owning methods: Wait owning methods: wait owning methods: wait owning methods: equals Owning methods: toString Owning methods: hashCode owning methods: getClass Owning methods: notify owning methods: notifyAll I love Java value is testCopy the code
  • getMethodsandgetFieldsMethod only readspublicattribute
  • Used when accessing private propertiesgetDeclaredMethodandgetDeclaredFieldAnd callsetAccessible(true)Modify its usability

As can be seen from the above, the use of reflection can bring a certain degree of security risks

7 Java中的IO

Program I/O can be decomposed into the following operations:

  1. The program initiates an I/O call request to the operating system
  2. The system kernel waits for the I/O device to prepare data
  3. The system kernel copies data from kernel space to user space

7.1 Blocking I/O

That is, block I/O synchronously, and the program waits until the I/O operation completes

7.2 Non – blocking I/O

The I/O multiplexing model

Synchronous non-blocking I/O uses polling, which is CPU intensive and almost impossible to use in Web development

The I/O multiplexing model uses a single thread for management, reducing the consumption of CPU resources by reducing invalid system calls

7.3 Asynchronous I/O

The asynchronous I/O model, in popular terms, is that the system kernel will execute the program-specified callback function after completion

Eight little detail

8.1 StringBuilderwithStringBufferThe difference between

StringBuilder threads are not safe

StringBuffer is thread-safe

8.2 Byte stream and character stream

Byte is a unit of measurement, indicating the amount of data. It is a unit of measurement used in computer information technology to measure storage capacity. Usually, one Byte is equal to eight bits

Characters are letters, numbers, words, and symbols used in computers that occupy different numbers of bytes in different encodings

Why provide character streams when there are byte streams in Java?

Because when the character encoding type is not known, the use of byte stream is prone to garble problems

It is better to use byte streams for audio files, pictures and other media files, or character streams if characters are involved