object-oriented

Three Java features

  • Encapsulation: Encapsulate the transaction as a class to decouple and hide the details. Through methods such as GET/SET, the internal logic is encapsulated and a specific interface is reserved to communicate with the outside world.
  • Inheritance: A new class is derived from a known class. The new class can have the behavior and properties of the known class and can be overridden/overridden to enhance the capabilities of the known class.
  • Polymorphic: The same implementation interface, using different instances to perform different operations. Inheritance is the basis of polymorphism, without inheritance there can be no polymorphism.

About the inheritance

  1. Java does not support multiple inheritance, which means that a class can have only one parent.
  2. Constructors in Java are not inheritable, and if a parent constructor is private, then subclasses are not allowed.
  3. Subclasses have properties and methods that are not private from their parent class
  4. Subclasses can add their own methods and attributes, which extend the parent class
  5. Subclasses can redefine methods of the parent class, that is, overrides/overrides of methods

About overwriting/overriding (@override)

Methods in a subclass have exactly the same return value types, method names, number of arguments, and parameter types as methods inherited from their parent class, but the subclass enriches or modifies functionality.

About the overloading

Overloading refers to the existence of multiple different methods with the same name in a class (including the parent class). The number of arguments, order, and type of these methods can constitute overloading of the method. These are the same methods if only the modifiers, return values, and exceptions thrown are different.

So it’s not an overload if the method returns a different value

Such as:

public int add(int a, int b){}
public void add(int a, int b){}
Copy the code

When you call the Add method, the system doesn’t know which one you want to call.

A transition between a subclass and a parent class

Suppose we have two classes, Father is the parent and Son is a subclass.

  1. upcasting

A subclass object becomes a parent class, which can be an interface.

Father f1 = new Son();
Copy the code

Question: In the process of upward transition, we easily method of leakage problems, such as a derived class (subclass) we will proceed upward transition, but may lack in the base class (parent) part of the derived class (subclass) method, so we to upcasting derived class (subclass), using a base class object to call methods (parent), Only methods of the base class (parent class) can be called.

  1. Downward transition

The superclass object is subclassed

Son s1 = (Son) f1;Copy the code

Note: The superclass must actually refer to a subclass object to force the type to be cast down. see the error below

Father f2 = new Father();
Son s2 = (Son)f2;
Copy the code

Why Son s1 = (Son) f1; Son s2 = (Son)f2; Transition failure? Since F1 refers to a subclass, but F2 is passed to a Father object, this means that the parent must actually refer to a subclass to force the type down

JDK, JRE, JVM

  • JDK: Java development kit, including JRE, also includes the Java compiler Javac, monitoring tool JConsole, analysis tool JVisualVM
  • JRE: A Java runtime environment that contains Java VMS and Java basic libraries
  • JVM: The Java virtual machine that converts bytecode into machine-specific code when we run a program, provides memory management/garbage collection, security mechanisms, etc

Differences and connections:

  • The JDK is a development kit for developing Java programs, while the JRE is the Java runtime environment
  • JVMS are included in both the JDK and JRE
  • The JVM is the core of Java programming, independent of hardware and operating system, and platform-independent, which is why Java programs can be written once and executed multiple times

How is the Platform independence of the Java language implemented?

  • The JVM shields the differences between the operating system and the underlying hardware
  • Java is programmed for the JVM by compiling to generate bytecode files, which are then handed to the JVM for interpretation into machine code
  • By specifying the range and behavior of basic data types

Abstract classes and interfaces

In Java, abstract classes are defined through abstract and interfaces are defined through the interface keyword

The main differences between abstract classes and interfaces can be summarized as follows:

  • An abstract class can have no abstract methods, or it can have both abstract and non-abstract methods
  • Methods in interfaces were only abstract prior to JDK8, which began to provide default implementations of methods in interfaces
  • Abstract classes are single-inherited like classes, but interfaces can inherit from more than one interface
  • Abstract classes can have ordinary member variables; Variables in the interface must be static final and must be initialized. There are only constants in the interface, no variables

Eight basic data types

The data type byte position
byte 1 8
short 2 16
int 4 32
long 8 64
float 4 32
double 8 64
char 2 16
boolean

Note: Boolean is not specified

==, equals, hashcode

background

  • == compares the (heap) memory addresses of objects stored in the variable (stack) memory to determine whether the addresses of two objects are the same, that is, whether they are the same object. We are comparing pointer operations in the true sense.
  • Equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals The equals method of Object returns a check for equals.
  • The hashCode() method is used to return a hashCode for a string. If two objects are the same, they must have the same hashCode value.

Conclusion:

  1. Comparing equals between compound data types is the same as the result of a double equals sign (==) without overwriting equals. If copied, follow the instructions.
  2. The = =
    • Is an operator
    • Basic type: Compares whether the values are the same
    • Reference type: compares whether the address values are the same
  3. For the equals ()
    • Is a way
    • Basic type: same as ==, both are comparison values
    • Reference type: By default, this method is used to compare the address values, but in some libraries this method is overridden (usually used to compare objects with the same member variables), for example: String, Integer, Date, etc., so they are no longer comparing the addresses of classes in the heap.
  4. The hashcode ()
    • Is a method that returns the hash code of an object
    • If two objects are equal using equals, their hashCode must be equal; If two objects are not equal through equals, then their hashCode may be equal;
    • To override equals, be sure to override hashCode

Static and non-static

  • Static variables: Modified by static. In the JVM, static variables are loaded before objects, so they do not exist attached to the object and can be used directly without instantiating the class
  • Instance variables (non-static) : They must be attached to the object and can only be used after the class has been instantiated.

The static keyword

Static is not static. Static is not static

  • The static modifier is static or global. The properties and methods to be modified belong to a class. The class name can be used. Static property/method name access
  • A static modified code block represents a static code block that is executed only once when the Java Virtual Machine (JVM) loads a class
  • Static modified properties, class variables, are created and initialized at class load time and are created only once
  • Static modified variables can be reassigned
  • The this and super keywords cannot be used in static methods
  • Static methods must be implemented, not abstract
  • Static methods cannot be overridden

annotations

An Annotation is essentially an interface that inherits the Annotation interface to associate any information or metadata with program elements (classes, methods, member variables, etc.). The program can retrieve annotation content through reflection.

The role of annotations

Simplify development by replacing complex configuration files.

Custom annotation

public @interface MyAnnotation { String value(); int value1(); } @myAnnotation (value1=100,value="hello") public class MyAnnotation {}Copy the code

As you can see from the code, annotations are defined using **@interface**, and attributes can be defined inside the method.

Yuan notes

The meta-annotation is responsible for the annotation of other annotations. Four meta-annotations are provided in Java.

  • @target: Indicates the scope of the object that the annotation modifies

The source code is as follows:

public @interface Target {  
    ElementType[] value();  
}  
public enum ElementType {  
  TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE  
}  
Copy the code

Use cases

@Target({ElementType.TYPE, ElementType.METHOD})  
public @interface MyAnnotation {  
}
Copy the code

Note: This indicates that MyAnnotation can only be scoped on classes/interfaces and methods.

  • @Retention: Retention policies define how long annotations are retained.

The source code is as follows:

public @interface Retention {  
    RetentionPolicy value();  
}  
public enum RetentionPolicy {  
    SOURCE, CLASS, RUNTIME  
}
Copy the code

Note: SOURCE: indicates that the SOURCE file is valid (that is, the SOURCE file is reserved). CLASS: indicates that it is valid in a CLASS file (that is, CLASS reserved). RUNTIME: indicates that it is valid at RUNTIME (that is, reserved at RUNTIME)

  • Documented: A Documented annotation is recognized by Javadoc and others
  • Inherited: Declare that A child class can inherit this annotation. When A class A uses this annotation, A child class of class A inherits this annotation

reflection

Reflection means that at runtime, all properties and methods of any given class can be known. For any object, you can call any of its methods and properties. That is, the function of dynamically retrieving information and calling object methods is called reflection mechanism.

Functionality provided by the Java reflection mechanism

  • Determine the class to which any object belongs at run time
  • Constructs an object of any class at run time
  • Determines or invokes member variables and methods that any class has at run time
  • Get generic information at run time
  • Annotations are processed at run time
  • Generating dynamic proxies

Advantages and disadvantages of Java reflection

Cons: Performance impact. Using reflection is basically an interpretive operation where we can tell the JVM what we want to do and it meets our requirements. This type of operation is always slower than performing the same operation directly.

The main API for reflection

  • Java.lang. Class: Represents a Class
  • Java.lang.reflect. Method: Represents the Method of a class
  • Java.lang.reflect. Field: Represents a member variable of the class
  • Java. Lang. Reflect. Constructor: on behalf of the Constructor of a class

Here’s an example:

package com.reflection; Public class Demo01 {public static void main(String[] args) throws ClassNotFoundException {/* Obtain the class object by reflection, * A Class has only one Class object, so c1, C2, and C3 have the same hashcode * When a Class is loaded, */ Class c1 = class.forname ("com.reflection.User"); System.out.println(c1.getName()); //com.reflection.User Class c2 = Class.forName("com.reflection.User"); System.out.println(c2.hashCode()); Class c3 = Class.forName("com.reflection.User"); System.out.println(c3.hashCode()); } // Pojo, entity, only attribute class User{private String name; private int age; public User(){ } public User(String name,int age){ this.age = age; this.name = name; } public void setName(String name) { this.name = name; } public String getName() { return name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; }}Copy the code

The results obtained are as follows:

com.reflection.User
356573597
356573597
Copy the code

C1, C2, c3 have the same hashcode. After a Class is loaded, the entire structure of the Class is encapsulated in the Class object.

Gets an instance of the Class Class

  • If a specific class is known, it can be obtained through the class attribute. This method is the most secure and reliable, and the program performance is the highest.Class class = Person.class;
  • Given an instance of a Class, call the instance’s getClass() method to get the Class object.Class class = person.getClass();
  • Given the full Class name of a Class that is on the classpath, it can be obtained through the static forName() method of the Class Class.Class class = Class forName("demo01. Student");
  • Built-in primitive data types can be used directly by class names. TypeClass c4 = Integer.TYPE;

Invokes the specified method

With reflection, call a Method in the class, done through the Method class.

  1. Class Class getMethod(String name,Clas… ParameterTypes takes a Method object and sets the parameterTypes needed to operate on the Method.
  2. Object invoke(Object obj, Object[] args) is then invoked and the parameter information of the obJ Object to be set is passed to the method.

Java exception Architecture

Exceptions are classified into Exception and Error

Throwable is the superclass for all errors and exceptions in the Java language. Throwable contains two subclasses: Error and Exception, which are usually used to indicate that an Exception has occurred.

What is the difference between Exception and Error?

  • An Exception is an Exception that is expected to occur during normal operation of a program and should be caught and handled accordingly. Exception is subdivided into runtime and compile-time exceptions.
    • Compile-time exception (checked exception) : Indicates that the currently invoked method body throws an exception, so the compiler detects that this code may raise an exception at runtime, so we must handle the exception accordingly, either catch the exception or throw it to the upper level caller.
    • Run-time exceptions (unchecked exceptions) : Indicates exceptions that occur at runtime. Common run-time exceptions include null pointer exceptions, array out-of-bounds exceptions, number conversion exceptions, arithmetic exceptions, and so on.
  • An Error is an Error that cannot occur under normal circumstances and causes the JVM to be in an unrecoverable state

Difference between NoClassDefFoundError and ClassNotFoundException?

  • NoClassDefFoundError is an Error type exception that is raised by the JVM and should not be attempted to catch. The cause of this exception is that when the JVM or ClassLoader tries to load a class, the definition of the class cannot be found in the memory. This action occurs during runtime, that is, the class exists at compile time, but cannot be found at runtime. It may be deleted after mutation or other reasons.
  • ClassNotFoundException is a checked exception that needs to be explicitly caught and processed using a try-catch, or declared with the throws keyword in the method signature. When using the Class. The class.forname, this loadClass. Or this findSystemClass dynamic Class is loaded into memory, didn’t find the Class through the incoming Class path parameters, throws the exception; Another possible reason for throwing this exception is that a class has been loaded into memory by one classloader and another loader tries to load it.

What principles should be followed for catching exceptions

  • Instead of using Exception capture, write out the Exception to catch in as much detail as possible;
  • Use log records to facilitate later troubleshooting;
  • Don’t use try-catch to wrap up large blocks of code, which is bad for troubleshooting;

Java exception handling keyword

What is the difference between throws and throws?

  • The throw keyword is used inside a method and can only be used to throw one exception. It can be used to throw an exception in a method or block of code.
  • Throws a list of exceptions that the method may throw. A method identifies a list of exceptions that may be thrown with throws. The method calling the method must contain code that can handle exceptions; otherwise, the method signature must declare the corresponding exception with the throws keyword.

Value passing and reference passing in Java

  • Value passing means that a copy of the object is passed, and even if the copy is changed, the source object is not affected.
  • Passing by reference means passing not the actual object, but a reference to the object. Therefore, external changes to reference objects are reflected in all objects.

Example of value passing

public class Test { public static void main(String[] args) { int x=0; change(x); System.out.println(x); } static void change(int i){ i=7; }}Copy the code

We all know that this is 0. If the parameter is a primitive data type, it is passed as a copy of the source object and does not affect the value of the source object.

Let’s look at another example of reference passing

public class Test {
    public static void main(String[] args)  {
        StringBuffer x = new StringBuffer("Hello");
        change(x);
        System.out.println(x);
    }
    static void change(StringBuffer i) {
        i.append(" world!");
    }
}
Copy the code

The output is Hello World!

Why not print Hello?

  • In ①, x refers to the heap memory, which holds Hello
  • In ②, I also refers to hello for heap memory
  • In ③, x and I refer to the same memory address, so append will directly modify the value inside the memory address
  • In ④, the method ends and the local variable I disappears

Let’s do another example

public class Test {
    public static void main(String[] args)  {
        StringBuffer x = new StringBuffer("Hello");
        change2(x);
        System.out.println(x);
    }
    static void change2(StringBuffer i) {
        i = new StringBuffer("hi");
        i.append(" world!");
    }
}
Copy the code

The output is Hello, which we also analyze by graph

As shown in the figure above, the function Change2 repoints the reference variable I to a different part of the heap, and the following changes are made to another part of the heap, so the output is Hello.

Let’s do one last example

public class Test {
    public static void main(String[] args)  {
        StringBuffer sb = new StringBuffer("Hello ");
        System.out.println("Before change, sb = " + sb);
        changeData(sb);
        System.out.println("After change, sb = " + sb);
    }
    public static void changeData(StringBuffer strBuf) {
        StringBuffer sb2 = new StringBuffer("Hi,I am ");
        strBuf = sb2;
        sb2.append("World!");
    }
}
Copy the code

Both output sb = Hello

Before change I’m sure everyone knows why. StrBuf = sb2, strBuf = sb2, strBuf = sb2, strBuf = sb2, strBuf = sb2, So the final output of sb is still Hello.

String, StringBuffer, and StringBuilder

They run at different speeds

String (iterated a million times)

String aa = ""; long startTime = System.currentTimeMillis(); for(int i=0; i<100*100*10; I++){// string concatenation aa = aa + "aa"; } long endTime = System.currentTimeMillis(); System.out.println(" Time: "+ string.valueof (endtime-startTime));Copy the code

Running results:

Time: 7614Copy the code

StringBuffer (traversed 100 million times)

StringBuffer aa = new StringBuffer(); String ss = "ss"; long startTime = System.currentTimeMillis(); for(int i=0; i<100*100*100*100; I++){// string concatenation aa.append(ss); } long endTime = System.currentTimeMillis(); System.out.println(" Time: "+ string.valueof (endtime-startTime));Copy the code

Running results:

Time: 3128Copy the code

StringBuilder (traversal 100 million times)

StringBuilder aa = new StringBuilder(); String ss = "ss"; long startTime = System.currentTimeMillis(); for(int i=0; i<100*100*100*100; I++){// string concatenation aa.append(ss); } long endTime = System.currentTimeMillis(); System.out.println(" Time: "+ string.valueof (endtime-startTime));Copy the code

Running results:

Time: 1240Copy the code

Speed comparison: String < StringBuffer < StringBuilder, and String processing speed is much slower than StringBuffer and StringBuilder

Why is String processing slower than StringBuffer and StringBuilder?

  • Strings are immutable objects
  • Stringbuffers and StringBuilders are mutable objects

(1) String itself is an object. Because String is immutable, an object will be recreated every time the String is concatenated. A million cycles will create a million objects, which consumes a lot of memory space. Creating objects a million times is time consuming. (2) StringBuffer and StringBuilder simply create a StringBuffer or StringBuilder object and concatenate the string with Append. Even if you concatenate 100 million times, you still have only one object.

Is it possible to get rid of strings and use StringBuffer and StringBuilder instead?

No way!

(1) String traversal code: first define a String constant (create a String object), then start traversal; (2) StringBuffer code: First define a String constant (create a String) and a create StringBuffer, then start iterating; The StringBuiler code starts by defining a String constant (to create a String object) and a create StringBuiler object, and then iterates;

(2) and (3) have one more object creation process than (1), so String is recommended for small data volumes.

What is the difference between StringBuffer and StringBuilder?

  • Stringbuffers are thread-safe
  • StringBuilder is non-thread-safe, which is why it is faster than StringBuffer

Usage scenarios?

(1) If you want to operate on a small amount of data, use String (2) to operate on a large amount of data in the String buffer

The generic

Generics are parameterized types that control parameters of specific types without creating new data types. The most common scenario for generics is in collections, simplifying development and ensuring code quality. Generics are valid at compile time, but are degenericized at run time, that is, the generic information is erased, which is why generic arrays are not supported.

  1. Through the syntactic definition of generics, the compiler can provide some type safety checks at compile time to filter out most run-time exceptions caused by type inconsistencies.
  2. Generics make program code more readable and, since they are just syntactic sugar, have no impact on JVM runtime performance.

Serialization and deserialization

Serialization keyword transient, which modifies variables that will not be serialized during object serialization.

Serialization means converting the state of an object into a stream of bytes from which an object in the same state can later be regenerated. Object serialization is an implementation method of object persistence, which converts the properties and methods of an object into a serialized form for storage and transmission. Deserialization is the process of rebuilding an object from this saved information.

Serialization: The process of converting Java objects into byte sequences.

Deserialization: The process of converting a sequence of bytes into Java objects.

Advantages:

A. Data persistence is implemented. Data can be permanently stored on hard disk (usually in a file) through serialization.

B. Use serialization to realize remote communication, that is, transmit the byte sequence of an object over the network.

Deserialization failure scenario:

Serialization ID: If serialVersionUID is inconsistent, deserialization fails

Java objects are destroyed when the JVM exits, and if objects need to be persisted, they need to be serialized, storing in-memory objects in a binary stream that can be deserialized as needed. Object serialization holds the state of the object; static variables that are class attributes are not serialized.

There are three common serialization: (1) Java native serialization, Serializabale implementation tag interface, compatibility is the best, but does not support cross-language, general performance. Serialization and deserialization must be consistent with the serialization ID. The private Static Final Long serialVersionUID is generally used to define the serialization ID. If not set, the compiler automatically generates this value based on the internal implementation of the class. (2) Hessian serialization, support dynamic type, cross-language. (3) JSON serialization, convert the data object to JSON string, abandon the type information, deserialization can only provide the type information can be accurate. It’s much more readable than the first two.

Serialization usually uses network transfer objects, which are vulnerable to attacks. Therefore, sensitive attributes that do not need to be serialized should be added with transient keyword, and the variable life cycle is limited to memory and will not be written to disk.

For details, see Java Basics —->Serializable usage