Features of Java#
- Object-oriented. Encapsulation, polymorphism, inheritance
- Good compatibility (Java Virtual Machine enables cross-platform, compile once, run on multiple platforms)
- Supports multithreading
- Supports network programming
- Compiled and interpreted
Write Once, Run Anywhere
JVM#
The Java Virtual Machine is a virtual machine that runs Java bytecode. JVM has specific implementations for different systems, aiming to produce the same execution results using the same bytecode, embodying the principle of compile once, run anywhere.
JRE and JDK#
JDK (Java Development Kit) is a fully functional Java SDK. In addition to containing the JRE, it also includes the compiler javac, tools javadoc, and jdb.
The JRE is the runtime environment for Java programs, a collection of what is needed to run compiled Java programs. It includes the JVM, Java class libraries, Java commands, and some basic components. Normally, using the JRE is sufficient to run Java programs; if you need to develop or compile Java programs, you must use the JDK.
If deploying WEB applications using JSP, the JDK is required. This is because the application server converts JSP into Java Servlets, which need the JDK for compilation.
Bytecode#
Code that the JVM can understand is called bytecode, and files with the .class extension contain it.
Bytecode solves the problem of low execution efficiency in traditional interpreted languages while retaining the advantages of interpreted languages.
Coexistence of Compilation and Interpretation#
Compiled: All code is translated into machine code at once by the compiler. Execution speed is fast but development efficiency is low. Examples include C, C++, Go, Rust.
Interpreted: Code is interpreted line by line into machine code and then executed by the interpreter. Development is fast but execution speed is slower. Examples include Python, PHP, JS.
The Java language has characteristics of both compiled and interpreted languages. Java programs undergo both compilation and interpretation processes.
Bytecode is generated into .class files through compilation, and then executed by the Java interpreter.
Basic Syntax#
continue, break, and return#
continue: Break out of the current loop iteration and continue with the next iteration.
break: Break out of the entire loop body and continue executing the code below the loop body.
return: Exit the current method and end its execution.
Member Variables and Local Variables#
- Syntax Form: Member variables belong to the class, while local variables belong to methods. Member variables can be modified by public, private, static modifiers, while local variables cannot. Both can be modified by final.
- Storage Method: If a member variable is modified by static, it belongs to the class; if not, it belongs to the instance. Objects are stored in the heap, while local variables are stored in the stack.
- Lifetime: Member variables are part of the object and are created with the object. Local variables are generated with method calls and end with the method's execution.
- Default Values: If a member variable is not assigned an initial value, it will automatically be assigned the default value of its type (e.g., boolean defaults to false, int defaults to 0, string defaults to null). Local variables will not be automatically assigned.
Static Variables#
Static variables can be shared by all instances of a class. Regardless of how many objects a class creates, they all share the same static variable.
Typically, static variables are modified by the final
keyword to become constants.
Character Constants and String Constants#
- Form: A character constant is a single character enclosed in single quotes, while a string constant is zero or more characters enclosed in double quotes.
- Meaning: A character constant is equivalent to an integer value (ASCII value) and can participate in expression calculations; a string constant represents an address value (the memory location where the string is stored).
- Memory Size: A character constant occupies 2 bytes; a string constant occupies several bytes.
Why Static Methods Cannot Call Non-Static Members#
Static methods belong to the class and are created when the class is loaded. Non-static members belong to instances and are created when an object is instantiated.
Static methods are created before non-static members.
Differences Between Static Methods and Instance Methods#
Calling Method: Static methods are called using ClassName.MethodName
. Instance methods are called using Object.MethodName
.
Overriding and Overloading#
Overloading#
Can only occur within the same class, method names must be the same, but parameter types, counts, and orders must differ; method return values and access modifiers can differ.
Overriding#
Occurs at runtime
- Method names and parameter lists must be the same, and return types must be the same.
- If the parent class's access modifier is
private/final/static
, the subclass cannot override that method.
Basic Data Types#
8 Data Types#
- 6 Numeric Types
- 4 Integer Types:
int\short\byte\long
- 2 Floating-point Types:
float\double
- 4 Integer Types:
- 1 Character Type:
char
- 1 Boolean Type:
boolean
Default Values and Memory Size#
Basic Type | Bits | Bytes | Default Value | Value Range |
---|---|---|---|---|
byte | 8 | 1 | 0 | -128 ~ 127 |
short | 16 | 2 | 0 | -32768 ~ 32767 |
int | 32 | 4 | 0 | -2147483648 ~ 2147483647 |
long | 64 | 8 | 0L | -9223372036854775808 ~ 9223372036854775807 |
char | 16 | 2 | 'u0000' | 0 ~ 65535 |
float | 32 | 4 | 0f | 1.4E-45 ~ 3.4028235E38 |
double | 64 | 8 | 0d | 4.9E-324 ~ 1.7976931348623157E308 |
boolean | 1 | 1 | false | true, false |
The long
type needs an L
after the value; otherwise, it will be parsed as an integer.
char a = 'h'
char: single quotes, String a = "hello"
: double quotes.
Differences Between Basic Types and Wrapper Types#
- Local variables of basic types are stored in the stack, while member variables of basic types are stored in the heap. Wrapper types belong to objects and are stored in the heap.
- The default value of wrapper types is null.
- Wrapper types can be used in generics, while basic types cannot.
Caching Mechanism of Wrapper Types#
- The four wrapper classes
Byte
,Short
,Integer
, andLong
create cached data for values in the range [-128, 127] by default. Character
creates cached data for values in the range [0, 127].Boolean
directly returnsTrue
orFalse
.Float
andDouble
do not have caching.
If a new variable is defined outside the range, a new object will be created.
Boxing and Unboxing#
- Boxing: Wrapping basic types with their corresponding reference types.
- Unboxing: Converting wrapper types back to basic data types.
Why Floating Point Arithmetic Loses Precision#
Infinite repeating decimals are truncated when stored in a computer, leading to a loss of decimal precision.
How to Solve Floating Point Precision Loss#
Use BigDecimal
.
How to Represent Data Exceeding lang
Types#
Use BigInteger
.
Basics of Object-Oriented Programming#
Object-Oriented vs. Procedural#
- Procedural: Breaks down the problem-solving process into methods, solving the problem through the execution of these methods.
- Object-Oriented: First extracts objects and solves the problem by executing methods on those objects.
Object Instances and Object References#
Object Reference: The instantiation of an object.
An object instance is created using new
(the object instance is stored in the heap), and the object reference points to the object instance (the object reference is stored in the stack).
An object reference can point to 0 or 1 object.
An object can have n references pointing to it.
Constructor#
Completes the initialization of an object. When instantiating an object, the parentheses indicate that the no-argument constructor is being called.
If no constructor is declared, a default no-argument constructor will be provided. If a parameterized constructor is declared, it will override the default no-argument constructor, and the no-argument constructor must be declared again manually.
The constructor must have the same name as the class, cannot be overridden, but can be overloaded.
Characteristics of Object-Oriented Programming: Encapsulation, Inheritance, Polymorphism#
Encapsulation#
Encapsulation refers to hiding an object's attributes within the object itself, preventing external objects from directly accessing the internal information of the object. However, attributes can be manipulated through some methods that are allowed to be accessed externally, such as get()
and set()
.
Inheritance#
- The subclass inherits all attributes and methods from the parent class, but cannot access private attributes and methods of the parent class.
- The subclass can create new attributes and methods, extending the parent class.
- The subclass can implement methods of the parent class in its own way.
Polymorphism#
- Compile-time Polymorphism: Refers to method overloading.
- Runtime Polymorphism: The specific type of the object reference defined in the program is determined during runtime.
Conditions for polymorphism: inheritance, overriding, and a parent class reference pointing to a subclass object (e.g., Animal a = new Cat()
).
Interfaces and Abstract Classes#
Similarities:
- Cannot be instantiated.
- Can contain abstract methods.
- Can have default implementation methods (defined using the default keyword in interfaces).
Differences:
- Single inheritance, multiple implementations.
- Member variables in interfaces can only be of type
public static final
and must have initial values. Member variables in abstract classes default todefault
and can be redefined and assigned in subclasses.
Deep Copy, Shallow Copy, Reference Copy#
- Shallow Copy: Creates a new object on the heap; if the original object's internal attributes are reference types, the shallow copy will directly reference the internal object's address, meaning the copied object and the original object share the same internal object.
- Deep Copy: Completely copies the entire object, including any internal objects contained within it.
- Reference Copy: Two different references point to the same object.
String Object#
Differences Between == and equals()#
- == checks whether references point to the same memory address in the heap.
- equals compares whether the contents in the heap are the same, not the addresses.
Overriding hashCode() Requires Overriding equals()#
Because different objects may have the same hashCode, but objects with different hashCodes must be different.
If only one is overridden, it may lead to situations where equals are the same but hashCodes are different.
When using HashSet, it first checks if the hashCodes are the same; if they are, it then uses the equals method to check for equality.
String, StringBuffer, StringBuilder#
StringBuffer
adds synchronization locks to methods, making it thread-safe.StringBuilder
does not add synchronization locks to methods, making it thread-unsafe.String
is immutable (the array that stores the string is marked asfinal
and is private); every time a change is made to aString
, a newString
object is created, and the pointer is directed to the newString
object.StringBuffer
operates on theStringBuffer
object itself each time, rather than generating a new object and changing the object reference.
Usage:
- For manipulating small amounts of data: use
String
. - For single-threaded operations on a string buffer with large amounts of data: use
StringBuilder
. - For multi-threaded operations on a string buffer with large amounts of data: use
StringBuffer
.
String Concatenation Should Not Use +
#
Using +
for concatenation actually calls the append()
method of StringBuilder
, and after concatenation, toString()
is called to obtain a String
object. When using +
in a loop, a new StringBuilder
object is created with each iteration; manually using StringBuilder
avoids this issue.
String.equals() vs. Object.equals()#
-
The
equals
method inString
is overridden to compare whether the values of the String objects are equal. -
The
equals
method inObject
compares the memory addresses of the objects.
String Constant Pool#
The string constant pool is a special area allocated to avoid the memory consumption caused by repeatedly creating String classes.
When a String type object is created, its content is saved in the heap, and the reference to the object is saved in the constant pool. When creating the same String object again, if an identical object already exists in the heap, the reference saved in the constant pool is returned directly.
How Many String Objects Are Created with String s1 = new String("abc")#
If the string "abc" has been created before, one string object will be created. If the string "abc" has not been created before, two string objects will be created.
intern Method#
The intern method saves the reference of the specified string object in the string constant pool.
- If the string constant pool already contains a reference to the corresponding string object, that reference is returned directly.
- If the string constant pool does not contain a reference to the corresponding string object, a reference pointing to that string object is created in the constant pool and returned.
String Type Variables and Constants in "+" Operations#
- If it is a string whose value can be determined at compile time, the JVM will place the reference of the concatenated string in the constant pool.
For example: String str3 = "str" + "ing"
will be optimized to String str3 = "string";
- If it is a string whose value cannot be determined at compile time,
StringBuilder
callsappend()
and then callstoString()
to obtain aString
.
Exceptions#
Exception and Error#
Java primarily has two types of exceptions: Exception and Error.
- Exception: Exceptions that the program can handle itself and can be caught using catch. Exceptions are divided into Checked Exception (must be handled) and Unchecked Exception (can be ignored).
- Error: Exceptions that the program cannot handle, which will cause the thread to terminate. For example, Java Virtual Machine runtime exceptions, memory overflow, stack overflow, etc.
Checked Exception and Unchecked Exception#
- Checked Exception is a checked exception; during compilation, if a checked exception is found that is not caught or thrown, compilation will fail.
- Except for RuntimeException and its subclasses, all other Exceptions are checked exceptions.
- Unchecked Exception is an unchecked exception; it can be ignored during compilation.
- RuntimeException and its subclasses are unchecked exceptions, common ones include: null pointer, array index out of bounds, etc.
Common Methods of Throwable Class#
getMessage()
returns a brief description of the exception.toString()
returns detailed information about the exception.getLocalizedMessage()
returns localized information about the exception object.printStackTrace()
prints the exception information encapsulated by the Throwable object to the console.
Usage of try-catch-finally#
- try: The user captures exceptions; it must be followed by either catch or finally.
- catch: Handles exceptions caught by try.
- finally: Will always be executed, regardless of whether an exception was caught or handled. If there is a return in try or catch, finally will execute before the method returns.
Will finally Always Execute?#
Not necessarily; if the JVM terminates before finally, it will not execute, nor will it execute if the thread where the program resides dies or the CPU shuts down.
Generics#
Ways to Use Generics#
- Generic classes
- Generic interfaces
- Generic methods
Reflection#
What is Reflection?#
Dynamically obtaining the class to which an object belongs during program execution, retrieving the class's member variables and methods, and invoking the class's properties and methods.
Where is Reflection Used?#
Spring uses annotations like @Component to obtain class information, properties, parameters, etc.
How to Use Reflection to Obtain a Class#
-
Using
ClassName.class
Class alunbarClass = TargetObject.class;
-
Using
Class.forName("ClassName")
Class alunbarClass1 = Class.forName("cn.javaguide.TargetObject");
-
Using the method
Object.getClass()
TargetObject o = new TargetObject(); Class alunbarClass2 = o.getClass();
-
Using the class loader
xxxClassLoader.loadClass()
to obtain the class path:ClassLoader.getSystemClassLoader().loadClass("cn.javaguide.TargetObject");
Annotations#
What are Annotations?#
Annotations can modify classes, methods, and variables, providing information for use during program compilation or runtime.
Ways to Parse Annotations#
- Scanning during compilation
- Processing through reflection during runtime
Reference Types#
Reference types determine whether an object can be garbage collected by the garbage collector ♻️.
Strong Reference#
Objects created using the new
keyword are strong references; strong reference objects will not be collected by GC.
Soft Reference#
Soft reference objects may be collected when memory is low. Soft reference objects can be created using the SoftReference
keyword.
Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj);
Weak Reference#
Weak reference objects are collected directly; created weak reference objects can only survive until the next GC occurs. Weak reference objects can be created using the WeakReference
keyword.
Object obj = new Object();
WeakReference<Object> wf = new WeakReference<Object>(obj);
Phantom Reference#
Phantom references cannot be used to obtain an object and do not affect the object. The purpose of phantom references is to receive a notification when the referenced object is garbage collected. Phantom reference objects can be created using the PhantomReference
keyword.
Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj);