This “Java Fundamentals Summary” is one of the most read articles on JavaGuide, and since I refactored it to improve it and fix a lot of small issues, let’s do a synchronization on SegmentFault!
The contents of the article are as follows:
Basic concepts and common sense
What are the features of the Java language?
- Simple and easy to learn;
- Object Oriented (encapsulation, inheritance, polymorphism);
- Platform independence (Java Virtual Machine implements platform independence);
- Support multi-threading (C++ language has no built-in multi-threading mechanism, so you must call the operating system’s multi-threading function to carry out multi-threading programming, while Java language has provided multi-threading support);
- Reliability;
- Security;
- It supports network programming and is very convenient (the Java language itself is designed to simplify network programming, so the Java language not only supports network programming but also is very convenient);
- Compiling and interpreting coexist;
Corrections (see also:
issue#544) : Since C++11 (2011),C++ has introduced a multithreading library, which is available on Windows, Linux, and MacOS
std::thread
and
std::async
To create threads. Reference link:
http://www.cplusplus.com/refe…
JVM vs JDK vs JRE
JVM
The Java Virtual Machine (JVM) is a virtual machine that runs Java bytecode. The JVM has specific implementations for different systems (Windows, Linux, MacOS) that aim to use the same bytecode, and they all give the same results.
What is bytecode? What are the benefits of adopting bytecode?
In Java, code that the JVM understands is called
The bytecode
(that is, extension name
.class
It is not intended for any particular processor, only for the virtual machine. By means of bytecode, Java language solves the problem of low execution efficiency of traditional interpreted languages to a certain extent, while retaining the portability of interpreted languages. So Java programs run efficiently, and because bytecode is not specific to a particular machine, Java programs can run on many different operating systems without having to be recompiled.
Java programs generally have the following three steps from source code to execution:
The.class-> machine code step is the one we need to pay special attention to. At this step, the JVM class loader first loads the bytecode file and then interprets it line by line through the interpreter, which is relatively slow. Also, some methods and blocks of code are called frequently (so-called hot code), so the JIT compiler was introduced later, and JIT is a run-time compilation. When the JIT compiler completes the first compilation, it saves the machine code corresponding to the bytecode for direct use the next time. As we know, machine code is definitely more efficient than the Java interpreter. This explains why we often say that Java is a language for both compilation and interpretation.
Hotspot uses Lazy Evaluation, and the 80-20 rule dictates that only a small portion of the code (hot code) consumes most of the system’s resources, and that this is what the JIT compiles. The JVM gathers information on each time the code is executed and makes some optimizations accordingly, so the more times it is executed, the faster it gets. JDK 9 introduced a new Compilation mode AOT(Ahead of Time Compilation), which is directly to compile bytecode into machine code, so as to avoid JIT warm-up and other overhead. The JDK supports layered compilation and collaborative use of AOT. However, the compilation quality of an AOT compiler is certainly not as good as that of a JIT compiler.
Conclusion:
The Java Virtual Machine (JVM) is a virtual machine that runs Java bytecode. The JVM has specific implementations for different systems (Windows, Linux, MacOS) that aim to use the same bytecode, and they all give the same results. Bytecode and JVM implementations on different systems are key to the Java language’s “compile once, run anywhere” approach.
The JDK and JRE
JDK stands for Java Development Kit, which is a fully functional Java SDK. It has everything a JRE has, along with a compiler (javac) and tools (such as Javadoc and JDB). It can create and compile programs.
The JRE is the Java runtime environment. It is the collection of everything you need to run a compiled Java program, including the Java Virtual Machine (JVM), Java class libraries, Java commands, and other infrastructure artifacts. However, it cannot be used to create new programs.
If you just want to run a Java program, all you need to do is install the JRE. If you need to do some Java programming work, you’ll need to install the JDK. However, this is not absolute. Sometimes, even if you don’t plan to do any Java development on your computer, you still need to install the JDK. For example, if you are deploying a Web application using JSPs, you are technically just running the Java program in the application server. So why do you need the JDK? This is because the application server converts the JSPs into Java servlets and requires the JDK to compile the servlets.
Why is the Java language “compiled and interpreted at the same time”?
High-level programming languages can be divided into compiled and interpreted languages according to how programs are executed. In simple terms, a compiled language is one in which a compiler translates source code into machine code that can be executed by a specific operating system at one time. An interpreted language is one in which the interpreter interprets the source program line by line into platform-specific machine code and executes it immediately. You want to read an English classics, for example, you can find a translator to help you read in English, there are two options, you can wait for the translator to complete the English classics (source) are translated into Chinese, to read, also can let a translator translation, you beside reading a, slowly get it done.
The Java language has the characteristics of both a compiled and interpreted language, in that Java programs are compiled first and then interpreted. Programs written in Java need to go through the compilation step to generate bytecode (\*.class files), which must be interpreted and executed by the Java interpreter. Therefore, we can think of Java language compilation and interpretation together.
Oracle JDK vs. OpenJDK
Probably many of you, like me, have never used OpenJDK before looking at this issue. So are there any major differences between Oracle and OpenJDK? Below I through the collection of some information, for you to answer this many people ignored the question.
With Java 7, there’s nothing critical about it. The OpenJDK project is primarily based on the HotSpot source code donated by Sun. In addition, OpenJDK was selected as the reference implementation for Java 7 and is maintained by Oracle engineers. The Oracle blog post in 2012 has a more detailed answer on the differences between the JVM, JDK, JRE, and OpenJDK:
Q: What is the difference between the source code in the OpenJDK repository and the code used to build the Oracle JDK?
A: Very close – our Oracle JDK build process is based on the OpenJDK 7 build, adding only a few parts, such as the deployment code, which includes Oracle’s Java plug-in and Java WebStart implementation, and some closed source code party components, Things like graphics rasterizers, some open source third-party components like Rhino, and bits and pieces like attached documents or third-party fonts. Going forward, our goal is to open source all parts of the Oracle JDK, except for those parts where we consider commercial functionality.
Conclusion:
- Oracle JDK releases major versions approximately every six months, while OpenJDK releases approximately every three months. But it’s not fixed, and I don’t think it’s useful to know that. For details, see: https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence.
- OpenJDK is a reference model and is fully open source, whereas Oracle JDK is an implementation of OpenJDK and is not fully open source;
- Oracle JDK is more stable than OpenJDK. The OpenJDK and Oracle JDK code is almost the same, but the Oracle JDK has more classes and some bug fixes. Therefore, if you want to develop enterprise/commercial software, I recommend the Oracle JDK as it is thoroughly tested and stable. In some cases, some people mentioned that they might be experiencing a lot of application crashes while using OpenJDK, but simply switching to Oracle JDK solved the problem;
- In terms of responsiveness and JVM performance, Oracle JDK provides better performance than OpenJDK;
- The Oracle JDK does not provide long-term support for upcoming releases. Users must obtain the latest version each time by updating to the latest version for support.
- Oracle JDK is licensed using the BCL/OTN protocol, while OpenJDK is licensed under the GPL V2 license.
π to expand:
- Oracle Binary Code License Agreement: The JDK can be used, but cannot be modified.
- Oracle Technology Network License Agreement (OTN) : Oracle Technology Network License Agreement (OTN) : Oracle Technology Network License Agreement (OTN) : Oracle Technology Network License Agreement (OTN) : Oracle Technology Network License Agreement (OTN) : Oracle Technology Network License Agreement (OTN) : Oracle Technology Network License Agreement (OTN) : Oracle Technology Network License Agreement (OTN)
Read π : “Differences Between Oracle JDK and OpenJDK”
What’s the difference between Java and C++?
I know a lot of people don’t learn C++, but interviewers like to compare Java with C++. No way!! Even if you haven’t learned C++, write it down!
- Both are object-oriented languages that support encapsulation, inheritance, and polymorphism
- Java does not provide Pointers to access memory directly, so program memory is more secure
- Java classes are single inheritance, C++ supports multiple inheritance; Although Java classes cannot be multiinherited, interfaces can be multiinherited.
- Java has an automatic memory management garbage collection (GC) mechanism that eliminates the need for the programmer to manually free up useless memory.
- C ++ supports both method overloading and operator overloading, but Java only supports method overloading (operator overloading adds complexity, which is at variance with Java’s original design philosophy).
- .
What is the difference between import Java and javax?
At the beginning, the required packages for JavaAPI were Java-beginning packages, and JavaX was just extending the API package to use. Over time, however, JavaX has gradually expanded to become part of the Java API. However, moving an extension from a Javax package to a Java package is really cumbersome and ends up breaking a bunch of existing code. As a result, it was decided that the JavaX package would become part of the standard API.
So, there is really no difference between Java and Javax. It’s all one name.
The basic grammar
What’s the difference between a character constant and a string constant?
- Format: A character constant is one character enclosed by a single quote, and a string constant is zero or more characters enclosed by a double quote
- Meaning: A character constant is equivalent to an integer value (ASCII value) and can participate in the expression operation. A string constant represents an address value (where the string resides in memory)
-
Memory size: The character constant is only 2 bytes; String constants are several bytes (note: char is two bytes in Java),
Character encapsulation class
Character
There is a member constant
Character.SIZE
The value is 16, and the units are
bits
, the value divided by 8(
1byte=8bits
) and you get 2 bytes
Java Programming Ideas Fourth Edition: Section 2.2.2
![]()
annotation
There are three types of comments in Java:
- Single-line comments
- Multiline comment
- Document comments.
When we write code, it can be easily understood by ourselves or other team members if the amount of code is small, but once the project structure becomes complex, we need to use comments. Comments are not executed (the compiler will erase all comments in the code before compiling it, no comments are kept in the bytecode). Comments are written by us programmers to ourselves. Comments are the specification of your code and help the person who is looking at the code to quickly understand the logical relationships between the code. Therefore, it is a good practice to add comments whenever you write a program.
The book Clean Code clearly states:
Comments to code are not as detailed as possible. In fact, good code itself is comments, we should try to standardize and beautify their code to reduce unnecessary comments.
If the programming language is expressive enough, you don’t need comments; try to explain them in code.
Here’s an example:
Remove the complex comment below and simply create a function that does the same thing as the comment says
// check to see if the employee is eligible for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
Should be replaced with
if (employee.isEligibleForFullBenefits())
What is the difference between an identifier and a keyword?
When we write programs, we need to name a lot of programs, classes, variables, methods, and so on. So we have an identifier. In simple terms, an identifier is just a name. But there are some identifiers that the Java language has given special meaning to that can only be used in certain places, and those special identifiers are keywords. Therefore, a keyword is an identifier that is given a special meaning. For example, in our daily life, the name “police station” has been given a special meaning, so if you open a shop, the name of the shop cannot be called “police station”, “police station” is the keyword in our daily life.
What are some common keywords in Java?
Access control | private | protected | public | ||||
---|---|---|---|---|---|---|---|
Class, method, and variable modifiers | abstract | class | extends | final | implements | interface | native |
new | static | strictfp | synchronized | transient | volatile | ||
Program control | break | continue | return | do | while | if | else |
for | instanceof | switch | case | default | |||
Error handling | try | catch | throw | throws | finally | ||
Package related | import | package | |||||
Basic types of | boolean | byte | char | double | float | int | long |
short | null | true | false | ||||
Variable reference | super | this | void | ||||
Reserved words | goto | const |
The increment and decrement operators
Java provides special operators for expressions like this, called the increment (++) and decrement (–) operators. For example, if a variable of type integer is required to increment or decrement by 1, Java provides special operators for such expressions.
The ++ and — operators can be placed before or after a variable. When the operator is placed before a variable (prefix), it is incremented/decrement first, then assigned; When an operator is placed after a variable (suffix), it is preassigned and then increments/decrements. For example, when b = ++a, it increments itself (increments itself by 1) and then assigns (assigns to b); When b = a++, preassign (assign to b), then increment (increment by itself). So, plus plus a prints the value of a plus 1, and a++ prints the value of a. In one formula, it is: “sign before add/subtract first, sign after add/subtract”.
What is the difference between continue, break, and return?
In a loop structure, when the loop condition is not met or the number of loops is met, the loop ends normally. However, sometimes it may be necessary to terminate the loop prematurely when certain conditions occur during the loop, which requires the following key words:
- Continue: To break out of the current loop and continue to the next one.
- Break: means to break out of the body of the loop and continue executing the statement below the loop.
Return is used to break out of the method and end the execution of that method. Return can be used in two ways:
return;
: Execute directly with the return end method, for methods that do not return a valuereturn value;
: return A specific value for a method that has a return value
Do you know Java generics? What is type erasure? What about some common wildcards?
Java generics, a new feature introduced in JDK 5, provide compile-time type safety checking, which allows programmers to detect illegal types at compile time. The nature of generics is that they are parameterized types, which means that the data type being manipulated is specified as a parameter.
Java generics are pseudo-generics because all generic information is erased during Java compilation, which is known as type erasure.
List<Integer> list = new ArrayList<>(); list.add(12); List.add ("a"); list.add("a"); Class<? extends List> clazz = list.getClass(); Method add = clazz.getDeclaredMethod("add", Object.class); Invoke (list, "kl"); // Add. Invoke (list, "kl"); System.out.println(list);
Generics are generally used in three ways: generic classes, generic interfaces, and generic methods.
1. Generic class:
Public class Generic<T>{private T key; public class Generic<T>{private T key; private T key; public Generic(T key) { this.key = key; } public T getKey(){ return key; }}
How to instantiate a generic class:
Generic<Integer> genericInteger = new Generic<Integer>(123456);
2. Generic interface:
public interface Generator<T> {
public T method();
}
Implement a generic interface without specifying a type:
class GeneratorImpl<T> implements Generator<T>{ @Override public T method() { return null; }}
Implement a generic interface, specifying the type:
class GeneratorImpl<T> implements Generator<String>{ @Override public String method() { return "hello"; }}
3. Generic methods:
public static < E > void printArray( E[] inputArray )
{
for ( E element : inputArray ){
System.out.printf( "%s ", element );
}
System.out.println();
}
Use:
IntArray = {1, 2, 3}; intArray = {1, 2, 3}; String[] stringArray = { "Hello", "World" }; printArray( intArray ); printArray( stringArray );
The commonly used wildcards are: T, E, K, V,?
- ? Represents an indeterminate Java type
- T (type) represents a concrete Java type
- K and V (key values) respectively represent the key values in the Java key values
- E of element stands for element
The difference between == and equals
For basic data types, == compares values. For reference data types, == compares the object’s memory address.
Because Java only passes values, for ==, whether comparing a primitive data type or a variable referring to a data type, the essence of the comparison is the value, except that the value stored in a variable referring to a type is the address of the object.
The equals() function cannot be used to determine whether two objects are equal or not. The equals() method exists in the Object class, which is the direct or indirect parent of all classes.
Object equals() method:
public boolean equals(Object obj) {
return (this == obj);
}
The equals() method can be used in two ways:
- Class not overridden
equals()
methodsThrough:equals()
When comparing two objects of this class, it is equivalent to comparing two objects by “==”, using the defaultObject
classequals()
Methods. - Class covers
equals()
methods: We usually cover them allequals()
Method to compare whether properties in two objects are equal; Returns true if their properties are equal (that is, the two objects are considered equal).
Here’s an example:
public class test1 { public static void main(String[] args) { String a = new String("ab"); String b = new String("ab"); String aa = "ab"; // String aa = "ab"; String bb = "ab"; If (aa ==bb) // true system.out. println("aa==bb"); If (a ==b) // false, System.out.println("a==b"); if (a.equals(b)) // true System.out.println("aEQb"); If (42 == 42.0) {// true system.out. println("true"); }}}
Description:
String
In theequals
The method is overridden becauseObject
ηequals
Method is to compare the object’s memory address, whileString
ηequals
Methods compare the values of objects.- When creating a
String
Object of type, the VM looks in the constant pool to see if there is an existing object with the same value as the one to create, and assigns it to the current reference. If not, create a new one in the constant poolString
Object.
String equals() method:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- ! = 0) { if (v1[i] ! = v2[i]) return false; i++; } return true; } } return false; }
HashCode () and equals ()
The interviewer may ask you, “Have you overridden hashCode and equals, and why is it necessary to override hashCode when you overrode equals?”
1) the hashCode () is introduced:
The purpose of hashCode() is to get a hashCode, also known as a hashCode; It actually returns an int integer. The hash code is used to determine the object’s index position in the hash table. HashCode () is defined in the JDK’s Object class, which means that any class in Java contains a hashCode() function. It is also important to note that the Object’s hashCode method is native, that is, implemented in C or C ++, and is usually used to convert the Object’s memory address to an integer and return it.
public native int hashCode();
The hash table stores key-value pairs. Its characteristic is that it can quickly retrieve the corresponding “value” according to the “key”. This is where the hash code is used! (You can quickly find the object you need)
2) Why HashCode?
Let’s use the example “How does a HashSet check for duplicates” to illustrate why there is a HashCode?
When you add an object to a HashSet, the HashSet will calculate the object’s HashCode value to determine where the object was added. It will also compare the HashCode values of other objects that have been added. If there is no matching HashCode, A HashSet assumes that the object does not occur repeatedly. However, if objects with the same hashCode value are found, the equals() method is called to check if objects with equal hashCode are really the same. If they are the same, the HashSet will not let them join successfully. If it is different, it will be rehashed to another location. (Excerpt from my Java primer, Head First Java, 2nd Edition). In this way, we have greatly reduced the number of equals times, which in turn has greatly increased the execution speed.
3) Why rewriteequals
Must be rewritten whenhashCode
Methods?
If two objects are equal, then hashCode must be the same. Two objects are equal. Calls to equals on both objects return true. However, if two objects have the same hashCode value, they are not necessarily equal. Therefore, if the equals method is overridden, the hashCode method must also be overridden.
hashCode()
The default behavior of is to generate unique values for objects on the heap. If I didn’t rewrite it
hashCode()
, two objects of the class will never be equal in any case (even if they point to the same data).
4) Why are two objects with the same hashCode value not necessarily equal?
Here, explain a little friend’s problem. The following is excerpted from Head Fisrt Java.
Because the hash algorithm used by hashCode() might just have multiple objects return the same hash value. The worse the hash algorithm is, the more likely it is to collide, but this is also due to the nature of the distribution of the data range (colliding means that different objects get the same hashCode).
We just mentioned HashSets. If a HashSet is comparing multiple objects of the same HashCode, it will use equals() to determine if it is indeed the same. In other words, hashCode is only used to narrow down the lookup cost.
More about hashCode() and equals() can be found in: Java hashCode() and equals() Problem Solvers
Basic data types
What are the basic data types in Java? What is the corresponding packaging type? How many bytes does each take up?
There are eight basic data types in Java. They are:
- Six number types:
byte
,short
,int
,long
,float
,double
- 1 character types:
char
- 1 Boolean type:
boolean
.
The default values for the eight basic data types and the size of the space taken up are as follows:
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 |
In addition, for Boolean, the official documentation is undefined and depends on the JVM vendor’s specific implementation. Logically, it takes 1 bit, but in practice, it takes into account the efficient storage of the computer.
Note:
- Do you use in the Java
long
The type of data must be appended to the valueLOtherwise it will be resolved as an integer. char a = 'h'
Char: Single quotation marks,String a = "hello"
: double quotation marks.
Each of the eight basic types has a corresponding wrapper class: Byte, Short, Integer, Long, Float, Double, Character, Boolean.
A wrapper type that is not assigned is NULL, while a primitive type has a default value that is not NULL.
In addition, this problem can be analyzed at the JVM level first.
The basic data types are stored directly in local variables in the Java Virtual Machine Stack, while the wrapper types are object types, and we know that object instances reside in the heap. Basic data types take up very little space compared to object types.
“Deep Understanding of the Java Virtual Machine” : The local variable scale is a repository of basic data types known at compile time
Boolean, byte, char, short, int, float, long, double,
Object referenceThe reference type, which is different from the object itself, may be a reference pointer to the starting address of the object, or to a handle that represents the object, or some other location associated with the object.
Automatic packing and unpacking
- Boxing: Wrapping basic types with their corresponding reference types;
- Unpacking: Converts the packaging type to a basic data type;
For example:
Integer i = 10; Int n = I; / / split open a case
The bytecode of the above two lines is as follows:
L1
LINENUMBER 8 L1
ALOAD 0
BIPUSH 10
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
PUTFIELD AutoBoxTest.i : Ljava/lang/Integer;
L2
LINENUMBER 9 L2
ALOAD 0
ALOAD 0
GETFIELD AutoBoxTest.i : Ljava/lang/Integer;
INVOKEVIRTUAL java/lang/Integer.intValue ()I
PUTFIELD AutoBoxTest.n : I
RETURN
From the bytecode, we can see that boxing is a call to the valueOf() method of the wrapper class, and unboxing is a call to the xxxValue() method.
As a result,
Integer i = 10
Is equivalent toInteger i = Integer.valueOf(10)
int n = i
Is equivalent toint n = i.intValue()
;
Eight basic types of wrapper classes and constant pools
Most wrapper classes for Java base types implement constant pooling technology. Byte,Short,Integer, and Long create cache values of the corresponding type by default. Character creates cache values in the range [0,127]. Boolean returns True Or False.
Integer cache code:
/** * This method will always cache values in the range -128 to 127 (including endpoints) and can cache other values outside of this range. */ public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; }
Character
Cache source code:
public static Character valueOf(char c) { if (c <= 127) { // must cache return CharacterCache.cache[(int)c]; } return new Character(c); } private static class CharacterCache { private CharacterCache(){} static final Character cache[] = new Character[127 + 1]; static { for (int i = 0; i < cache.length; i++) cache[i] = new Character((char)i); }}
Boolean
Cache source code:
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
If a new object is created outside the corresponding range, the size of the range of the cache is only a tradeoff between performance and resources.
Two types of floating-point wrapper classes, Float,Double does not implement constant pooling technology.
Integer i1 = 33; Integer i2 = 33; System.out.println(i1 == i2); // print true Float i11 = 333f; Float i22 = 333f; System.out.println(i11 == i22); // Output false Double i3 = 1.2; Double i2 = 1.2; System.out.println(i3 == i4); / / output is false
Now let’s look at the problem. Is the output of the following code true or flase?
Integer i1 = 40;
Integer i2 = new Integer(40);
System.out.println(i1==i2);
Integer I1 =40 is unboxed, so this line of code is equivalent to Integer I1 =Integer.valueOf(40). Therefore, I1 works directly with objects in the constant pool. Integer i1 = new Integer(40) creates a new object directly.
Therefore, the answer is false. Are you right?
Remember to use the equals method for all comparisons between integer wrapper objects.
Methods (functions)
What is the return value of a method?
The return value of a method is the result of the execution of the code in a method body that we get! (provided the method is likely to produce results). The purpose of the return value is to receive the result so that it can be used for other operations!
What are the types of methods?
1. A method with no arguments and no return value
Public void f1() {System.out.println(" method with no arguments and no return value "); public void f1() {System.out.println(); }
2. A method with arguments and no return value
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} */ public void f2(int a, String b, int c) {System.out.println(a + "-->" + b + "-->" + c); }
3. There are methods that return values without arguments
Public int f3() {System.out.println();} public int f3() {System.out.println();} public int f3(); return 2; }
4. A method with a return value and parameters
Public int f4(int a, int b) {return a * b; }
5. Special use of return in no-return methods
Public void f5(int a) {if (a > 10) {return; } System.out.println(a);} System.out.println(a);} System.out.println(a); }
Why is it illegal to call a non-static member in a static method?
Static methods belong to a class, allocate memory when the class is loaded, and can be accessed directly by the class name. Non-static members belong to the instance object, exist only after the object is instantiated, and are then accessed through the instance object of the class. A static member exists when a non-static member of the class does not exist. It is illegal to call a non-static member that does not already exist in memory.
What is the difference between a static method and an instance method?
- When calling static methods externally, you can use the “class name. “Method name”, or “object name”. Method name “. Instance methods are only the latter. That is, calling a static method can be done without creating an object.
- When a static method accesses a member of the class, it is only allowed to access the static members (that is, static member variables and static methods), but not the instance member variables and instance methods. Instance methods have no such restriction.
Why is there only value passing in Java?
First, let’s review some of the terminology used in programming languages for passing parameters to methods (or functions).
A call by value means that a method receives a value provided by the caller, and a call by reference means that a method receives a variable address provided by the caller. A method can modify the value of a variable corresponding to a pass-through reference, but not the value of a pass-through call. It is used to describe how method parameters are passed in various programming languages, not just Java.
The Java programming language has always adopted call by value. That is, the method gets a copy of all the parameter values, which means that the method cannot modify the contents of any parameter variables passed to it.
Here are three examples to illustrate
example 1
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
swap(num1, num2);
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
}
public static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
System.out.println("a = " + a);
System.out.println("b = " + b);
}
Results:
a = 20
b = 10
num1 = 10
num2 = 20
Resolution:
In swap, the values of a and b are swapped without affecting num1 and num2. Because the values in a and b are just copied from num1 and num2. That is to say, a, b is equivalent to num1, num2 copies of the contents of the copy, no matter how to change, will not affect the original itself.
We’ve seen from the example above that a method cannot modify a parameter to a primitive data type, unlike object references as parameters. See example2.
example 2
public static void main(String[] args) { int[] arr = { 1, 2, 3, 4, 5 }; System.out.println(arr[0]); change(arr); System.out.println(arr[0]); } public static void change(int[] array) {array[0] = 0; }
Results:
1
0
Resolution:
Array is initialized as a copy of arr which is a reference to an object, which means that array and arr refer to the same array object. Therefore, external changes to the referenced object are reflected in the corresponding object.
As we’ve seen with example2, implementing a method to change the state of an object’s parameters is not difficult. The reason is simple. The method gets a copy of the object reference. The object reference and other copies refer to the same object.
Many programming languages (notably C++ and Pascal) provide two ways of passing parameters: value calls and reference calls. Some programmers (and even the authors of this book) think that the Java programming language makes reference calls to objects, which is, in fact, a misconception. Since this misconception is common to a certain extent, a counterexample is given below to elaborate on this problem in detail.
example 3
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Student s1 = new Student (" zhang "); Student s2 = new Student(" new Student "); 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()); }}
Results:
X: Xiao Li. Y: Xiao Zhang. S1: Xiao Zhang
Resolution:
Before exchange:
After the exchange:
It is clear from the above two figures that the method does not change the object references stored in the variables s1 and s2. The x and y arguments to swap are initialized as copies of the two object references that the method swaps
conclusion
The Java programming language does not make reference calls to objects; in fact, object references are passed by value.
Let’s summarize the use of method parameters in Java:
- A method cannot modify the parameters of a primitive data type (that is, numeric or Boolean).
- A method can change the state of an object parameter.
- A method cannot have an object parameter reference a new object.
Reference:
“Java Core Technology Volume β ” Fundamentals, 10th Edition, Chapter 4, Section 4.5
The difference between overloading and overriding
Overloading is the same method that can do different things with different input data
Overriding is when a subclass inherits the same method from the superclass, the same input data, but to make a different response from the superclass, you override the superclass method
overloading
In the same class (or between a parent class and a child class), the method name must be the same, the parameter type, number, order can be different, and the method return value and access modifier can be different.
Here’s Java Core Technology’s introduction to the concept of reloading:
To sum up: Overloading is when multiple methods in the same class with the same name perform different logical processing based on different arguments passed.
rewrite
Overwriting occurs at run time when a subclass rewrites its parent’s implementation of an accessible method.
- The return value type, method name, parameter list must be the same, the range of exception thrown is less than or equal to the parent class, and the range of access modifier is greater than or equal to the parent class.
- If the superclass method access modifier is
private/final/static
A subclass cannot override the method, but a method that has been static can be declared again. - The constructor cannot be overridden
To sum up: Overwriting is a subclass’s reconstruction of the superclass method. The external appearance cannot be changed, but the internal logic can be changed
Warm Guide brother finally come to a chart summary!
The mark | Overloaded methods | Overriding methods |
---|---|---|
In scope | The same class | A subclass |
The list of parameters | Must be modified | You must not modify it |
The return type | Can be modified | The return value type of a subclass method should be smaller or equal to that of a superclass method |
abnormal | Can be modified | The exception class thrown by a subclass method declaration should be smaller or equal than the exception class thrown by a superclass method declaration. |
Access modifier | Can be modified | Make sure you don’t limit yourself more severely (you can lower the limit) |
Stage of development | Compile time | The run-time |
Methods should be overwritten to follow the “two with the same, two with the same, one with the smaller” (this is excerpted from the Crazy Java handout,issue#892) :
- “Two identical” means that the method name is the same and the parameter list is the same;
- “Two small” means that the return value type of the subclass method should be smaller or equal than that of the parent method, and that the exception class declared by the subclass method should be smaller or equal than that declared by the parent method.
- “One” means that subclass methods should have greater or equal access than superclass methods.
If the return type of the method is void and a primitive data type, the return value cannot be modified when the method is overridden. However, if the return value of a method is a reference type, it is possible to override the method to return a subclass of that reference type.
Public class Hero {public String name() {return "Hero "; }} public class Superman extends Hero{@Override public String name() {return "Superman "; } public Hero hero() { return new Hero(); }} public class SuperMan extends SuperMan {public String name() {return "SuperMan "; } @Override public SuperMan hero() { return new SuperMan(); }}
Deep copy vs. shallow copy
- Shallow copy: pass-by-value of the base data type, pass-by-reference copy of the reference data type, which is a shallow copy.
- Deep copy: Passing values to the base data type, creating a new object to the reference data type, and copying its contents. This is a deep copy.
Java Object-oriented
The difference between object orientation and procedure orientation
- Process Oriented: Process oriented performance is higher than object oriented. Because class invocation needs to be instantiated, which costs more and consumes more resources, so when performance is the most important factor to consider, such as microcontroller, embedded development, Linux/ UNIX, etc., process oriented development is generally adopted. However, process – oriented is not as easy to maintain, reuse and extend as object – oriented.
- Object-Oriented: Object-Oriented is easy to maintain, easy to reuse, easy to extend. Because of the characteristics of object – oriented encapsulation, inheritance and polymorphism, it is possible to design a system with low coupling, which makes the system more flexible and easier to maintain. However, object-oriented performance is lower than procedural performance.
See Issue: Process-Oriented: Process-Oriented Performance Is Better Than Object-Oriented?
This is not the root cause. Procedure-oriented also needs to allocate memory and calculate memory offsets. The main reason for Java’s poor performance is not because it is an object-oriented language, but because Java is semi-compiled and the final executable code is not binary mechanical code that can be directly executed by the CPU.
However, most of the process-oriented languages are directly compiled into mechanical code and executed on the computer, and the performance of other process-oriented scripting languages is not necessarily better than Java.
What are the differences between a member variable and a local variable?
- Syntactically, a member variable belongs to a class, while a local variable is a variable or parameter to a method defined in a block of code or method. Member variables can be
public
.private
.static
Local variables cannot be modified by the access control modifierstatic
The modification; However, both member and local variables can be usedfinal
The modification. - From the way the variable is stored in memory, if the member variable is used
static
Modified, then the member variable belongs to the class if not usedstatic
This member variable belongs to the instance. While objects reside in heap memory, local variables reside in stack memory. - In terms of how long a variable lives in memory, a member variable is a part of an object that exists when the object is created, while a local variable disappears automatically when a method is called.
- If a member variable is not initially assigned, it is automatically assigned to the default value of the type, depending on whether the variable has a default value (except in one case: by
final
Decorated member variables must also be explicitly assigned), whereas local variables are not automatically assigned.
What operator is used to create an object? What is the difference between object entities and object references?
The new operator, which creates an instance of the object (which is in heap memory) and an object reference to the object (which is in stack memory).
An object reference can refer to zero or one object (a string can be tied without a balloon or with a balloon); An object can have n references pointing to it (a balloon can be tied with n ropes).
What is the difference between the equality of objects and the equality of references to them?
Object equality, compared to the memory stored content is equal. References that are equal compare whether the memory addresses they point to are equal.
What is the purpose of a class constructor? If a class does not declare a constructor, will the program execute correctly? Why is that?
The constructor is used to initialize a class object.
If a class does not declare a constructor, it can also be executed! Because a class that does not declare a constructor will have a default constructor that takes no arguments. If we add our own class constructor (with or without arguments), Java will no longer add the default no-argument constructor. In this case, we can’t simply new an object without passing arguments, so we keep using constructors without realizing it. This is why we put a parenthesis after the creation of the object (because we are calling the constructor without arguments). If we overload a constructor with arguments, remember to also write the constructor with no arguments (whether we use it or not), because this will help us create objects with less cramps.
What are the characteristics of a constructor? Can it be overridden?
Features:
- The name is the same as the class name.
- There is no return value, but you cannot declare a constructor with void.
- The object of the class is generated automatically without a call.
Constructors cannot be overridden, but can be overloaded, so you can see more than one constructor in a class.
Three characteristics of object-oriented
encapsulation
Encapsulation means to hide an object’s state information (that is, its properties) inside the object, and not allow external objects to directly access the object’s internal information. However, you can provide methods that can be accessed by the outside world to manipulate properties. Just like we can’t see the part information (i.e. properties) inside the air conditioner hanging on the wall, but we can control the air conditioner by the remote control (method). If properties don’t want to be accessed by outsiders, we don’t need to provide methods for outsiders to access them. But if a class does not provide methods for outsiders to access, then the class is meaningless. Just as we can’t control air conditioning if we don’t have a remote control for air conditioning, the air conditioning itself is meaningless (of course there are many other methods, but this is just for example).
public class Student { private int id; Private String name; // private String name; Public int getId() {return id; getId() {return id; } public void setId(int id) {this.id = id; } public String getName() {return name; } public void setName(String Name) {this.name = name; }}
inheritance
Objects of different types often have a certain amount in common with each other. For example, Xiao Ming, Xiao Hong and Xiao Li all share the characteristics of students (class, student number, etc.). At the same time, each object defines additional features that make them unique. For example, Xiao Ming is good at math and Xiao Hong has a charming personality. Xiao Li has more strength. Inheritance is the technique of creating a new class based on the definition of an existing class. The definition of a new class may add new data or new functionality, or may use the functionality of the parent class, but it cannot selectively inherit from the parent class. By using inheritance, we can quickly create new classes, improve code reuse, program maintainability, save a lot of time to create new classes, and improve our development efficiency.
Here are three things to remember about inheritance:
- The subclass owns all the properties and methods (including private properties and methods) of the superclass object, but the private properties and methods in the superclass are not accessible to the subclass and are only owned.
- Subclasses can have their own properties and methods, that is, subclasses can extend their superclasses.
- A subclass can implement the methods of its parent class in its own way. (More on this later).
polymorphism
Polymorphism, as the name suggests, means that an object has multiple states. A reference to a parent class points to an instance of a child class.
Characteristics of polymorphism:
- There is an inheritance (class)/implementation (interface) relationship between object types and reference types.
- The method in which a method call from a type variable is invoked must be determined during program execution.
- Polymorphism cannot call methods that exist only in the child class but not in the parent class;
- If a subclass overrides a method of the superclass, it actually executes the method overridden by the subclass. If a subclass doesn’t override a method of the superclass, it executes the method of the superclass.
What is the difference between String StringBuffer and StringBuilder? Why is String immutable?
variability
The final char value is a private final char value[], so the String is immutable. The final char value is a private final char value.
Supplement (from
issue 675) : After Java 9, String,
StringBuilder
δΈ
StringBuffer
The implementation uses a byte array to store strings
private final byte[] value
Both StringBuilder and StringBuffer inherit from the AbstractStringBuilder class. AbstractStringBuilder also uses a character array to hold the string char[]value but is not modified with the final keyword, so both types of objects are mutable.
The StringBuilder and StringBuffer constructors are implemented by calling the parent class constructor, i.e. AbstractStringBuilder. You can check the source code for yourself.
AbstractStringBuilder.java
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
/**
* The count is the number of characters used.
*/
int count;
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}}
Thread safety
Objects in a String are immutable, which means they are considered constant and thread-safe. AbstractStringBuilder is the public parent of StringBuilder and StringBuffer. It defines some basic string operations, such as public methods such as ExpandCapacity, Append, Insert, IndexOf, etc. StringBuffer is thread-safe because it applies a synchronization lock to a method or to a method it calls. StringBuilder does not lock the method synchronously, so it is not thread safe.
performance
Each time the String type is changed, a new String is generated and a pointer is directed to the new String. Instead of generating new objects and changing object references, StringBuffer operates on the StringBuffer object itself each time. Using StringBuilder in the same case only gives a performance improvement of around 10% to 15% over using StringBuffer, but runs the risk of being unsafe for multiple threads.
Summary of the use of the three:
- Manipulating small amounts of data: applicable
String
- Single-threaded manipulation of large amounts of data under string buffers: applicable
StringBuilder
- Multithreading manipulation of large amounts of data under string buffers: applicable
StringBuffer
Summary of common methods of the Object class
The Object class is a special class that is the parent of all classes. It mainly provides the following 11 methods:
public final native Class<? > getClass()//native method, used to return the Class object of the current runtime object, is modified with the final keyword, so subclass overrides are not allowed. Public Native int hashCode() // Native method to return the hashCode of an object. This method is mainly used in hash tables, such as the JDK's HashMap. Public Boolean equals(Object obj) public Boolean equals(Object obj) public Boolean equals(Object obj) public Boolean equals(Object obj) public Boolean equals(Object obj) public Boolean equals(Object obj) Protected native Object clone () throws CloneNotSupportedException / / naitive method, is used to create and return a copy of the current Object. In general, for any object x, the expression x.lone ()! X = true, x.lone ().getClass() == x.getClass(); Object does not implement the Cloneable interface, so don't rewrite the clone method and call CloneNotSupportedException abnormal happens. Public String toString()// Returns a hexadecimal String with the name of the class @ the instance of the hash. It is recommended that all subclasses of Object override this method. Public final Native void notify()// Native method, and cannot overwrite. Wake up a thread that is waiting on this object's monitor (the monitor is equivalent to the concept of a lock). If there are multiple threads waiting, only one will wake up at will. Public void notifyAll() public void notifyAll() public void notifyAll() public void notifyAll() As with Notify, the only difference is that instead of one thread, all threads waiting on this object monitor are awakened. Public final native void wait (long timeout) throws InterruptedException / / native methods, and cannot be rewritten. Pause the execution of the thread. Note: The sleep method does not release the lock, whereas the wait method does. Timeout is the waiting time. Public final void wait(long timeout, int nanos) throws InterruptedException// The range is 0-999999). So we have to add nanos milliseconds to the timeout. Throws InterruptedException public final void wait() throws InterruptedException// Protected void finalize() throws Throwable {}// The operation that is emitted when an instance is collected by the garbage collector
reflection
What is reflection?
If you’ve studied the underlying principles of a frame or if you’ve written a frame yourself, you’re familiar with the concept of reflection.
Reflection is called the soul of a framework primarily because it gives us the ability to analyze a class and execute its methods at run time.
You can get all the properties and methods of any class through reflection, and you can also call those methods and properties.
Advantages and disadvantages of reflection mechanism
- Advantages: It makes our code more flexible and makes it easier to provide out-of-the-box functionality for various frameworks
- Disadvantages: gives us the ability to analyze operation classes at run time, which also increases security concerns. For example, you can ignore security checks for generic parameters (which occur at compile time). In addition, the reflection performance is slightly worse, but the actual effect on the framework is not significant. Java Reflection: Why is it so slow?
Reflection application scenarios
As we usually most of the time is writing business code, will rarely come into contact with the direct use of reflection mechanism of the scene.
However, this does not mean that reflection is useless. On the contrary, reflection is what makes it so easy to use frameworks. Frameworks such as Spring/Spring Boot, MyBatis and so on make extensive use of reflection.
These frameworks also make heavy use of dynamic proxies, whose implementation also relies on reflection.
For example, here is an example code that implements a dynamic proxy via the JDK, which uses the reflection class Method to call a specified Method.
Public class DebugInvocationHandler implements InvocationHandler {/** * private Final Object Target; public DebugInvocationHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException { System.out.println("before method " + method.getName()); Object result = method.invoke(target, args); System.out.println("after method " + method.getName()); return result; }}
In addition, implementations like annotations, one of the most powerful tools in Java, also use reflection.
Why does an @Component annotation declare a class as a Spring Bean when you use Spring? Why do you read the Value from the configuration file with an @Value annotation? How exactly does it work?
This is all because you can analyze classes based on reflection and then get annotations on class/property/method/method parameters. Once you get the annotations, you can do further processing.
abnormal
Java exception class hierarchy diagram
pictures from: https://simplesnippets.tech/e…
pictures from: https://chercher.tech/java-pr…
In Java, all exceptions have a common ancestor, the Throwable class in the java.lang package. The Throwable class has two important subclasses: Exception and Error. Exception can be handled by the program itself (try-catch). Error cannot be handled (can only be avoided).
Both Exception and Error are important subclasses of Java Exception handling, and each contains a large number of subclasses.
Exception
Exceptions that can be handled by the program itself can be passedcatch
To capture.Exception
It can be divided into checked exceptions (which must be handled) and unchecked exceptions (which can be left unhandled).Error
οΌError
It’s an error that the program can’t handle. We can’t pass itcatch
To capture. For example, the Java Virtual Machine runs an error (Virtual MachineError
), not enough virtual machine memory (OutOfMemoryError
), class definition error (NoClassDefFoundError
), etc. When these exceptions occur, the Java Virtual Machine (JVM) typically chooses to terminate the thread.
Abnormal under examination
Java code cannot be compiled if the checked exception is not handled by a catch/throw during compilation. Take the following IO operation code.
With the Exception of RuntimeException and its subclasses, all Exception classes and their subclasses are checked exceptions. IO related exceptions, ClassNotFoundException, SQLException… .
No checked exceptions
Java code can compile without handling unchecked exceptions during compilation.
RuntimeException and its subclasses are collectively called unchecked exceptions, for example: NullPointerException, a NumberFormatException (string is converted to digital), ArrayIndexOutOfBoundsException (an array), a ClassCastException (type conversion error), Ari ThmeticException (arithmetic error).
Throwable common methods
- Public String getMessage(): Returns a brief description of when the exception occurred
- Public String toString(): Returns details about when an exception occurs
public string getLocalizedMessage()
: Returns localization information for the exception object. useThrowable
This method is overridden by a subclass of the If the subclass does not override the method, the information returned by the method is similar toGetMessage ()
The same result is returnedpublic void printStackTrace()
: Print on the consoleThrowable
Object encapsulated exception information
try-catch-finally
try
Block:Used to catch exceptions. It can be followed by zero or morecatch
Block, if notcatch
Block must be followed by onefinally
Block.- Catch block: Used to handle exceptions caught by the try.
finally
Block:Whether or not exceptions are caught or handled,finally
The statements in the block are executed. When intry
Block orcatch
Encountered in the blockreturn
The statement,finally
The block is executed before the method returns.
In the following three special circumstances,finally
Block will not be executed:
- in
try
ζfinally
Using a piece ofSystem.exit(int)
Exit the program. But ifSystem.exit(int)
After the exception statement,finally
It’s still going to be enforced - The thread on which the program was running died.
- Close the CPU.
The following part from issue:https://github.com/Snailclimb… .
Note: When there is a return in both a try statement and a finally statement, the contents of the finally statement will be executed before the method returns, and the return value of the finally statement will override the original return value. As follows:
public class Test { public static int f(int value) { try { return value * value; } finally { if (value == 2) { return 0; }}}}
If f(2) is called, the return value will be 0, because the finally statement overrides the try block’s return value.
usetry-with-resources
To take the place oftry-catch-finally
- Scope of application (resource definition) :Any implementation
java.lang.AutoCloseable
orjava.io.Closeable
The object of - The order in which resources and finally blocks are closed: ε¨
try-with-resources
Statement in which any catch or finally block runs after the declared resource is closed
Effecitve Java clearly states:
Resources that must be closed should always be used first
try-with-resources
Rather than
try-finally
. The resulting code is shorter and cleaner, and the resulting exceptions are more useful to us.
try-with-resources
Statements make it easier to write code for resources that must be closed if used
try-finally
You can hardly do that.
Java resources such as InputStream, OutputStream, Scanner, PrintWriter and so on require us to call the close() method to close manually. In general, we use the try-catch-finally statement to achieve this requirement. As follows:
Scanner = null; // Scanner = null; try { scanner = new Scanner(new File("D://read.txt")); while (scanner.hasNext()) { System.out.println(scanner.nextLine()); } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (scanner ! = null) { scanner.close(); }}
Use the try-with-resources statement after Java 7 to modify the above code:
try (Scanner scanner = new Scanner(new File("test.txt"))) {
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
Try -with-resources are easy to use when multiple resources need to be closed, but if you use try-catch-finally, it will cause a lot of problems.
Multiple resources can be declared in a try-with-resources block by using semicolon separation.
try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new File("test.txt"))); BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt")))) { int b; while ((b = bin.read()) ! = -1) { bout.write(b); } } catch (IOException e) { e.printStackTrace(); }
The I/O stream
What is serialization? What is deserialization?
If we need to persist Java objects, such as storing them in a file or transferring them over a network, these scenarios require serialization.
In short:
- Serialization: The process of converting a data structure or object into a binary byte stream
- Deserialization: The process of converting a stream of binary bytes generated during serialization into a data structure or object
In an object-oriented programming language like Java, all we serialize are objects that are instantiated classes, but in a semi-object-oriented language like C++, struct defines the type of a data structure and Class corresponds to the type of an Object.
Here’s what Wikipedia says about serialization:
serializationIn data processing in computer science, the process of converting the state of a data structure or object into a desirable format (such as storing it as a file, storing it as a buffer, or sending it over a network) so that it can be restored to its original state later in the same or another computer environment. When the result of retrieving a byte in a serialized format, it can be used to produce a copy with the same semantics as the original object. For many objects, such as complex objects that use a large number of references, this serialization reconstruction process is not easy. Object serialization in object orientation does not generalize the functions that the original object was related to. This process is also known as object marshalling. The reverse operation of extracting data structures from a sequence of bytes is deserialization (also known as unmarshalling, deserialization, and unmarshalling).
To summarize: The main purpose of serialization is to transfer objects over a network or store them in a file system, database, or memory.
https://www.corejavaguru.com/…
What if there are fields in Java serialization that you don’t want to serialize?
Use transient keywords for variables that you do not want to serialize.
A transient keyword prevents serialization of variables in an instance that have been modified with this keyword. When an object is deserialized, transient variable values are not persisted and restored. Transients can only modify variables, not classes and methods.
Gets two common ways of typing with a keyboard
Method 1: Go through Scanner
Scanner input = new Scanner(System.in);
String s = input.nextLine();
input.close();
Method 2: Use BufferedReader
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String s = input.readLine();
How many types of IO streams are there in Java?
- According to the flow direction, it can be divided into input flow and output flow;
- According to the operation unit, it can be divided into byte stream and character stream.
- The flow is divided into a node flow and a processing flow according to its role.
The Java IO stream involves more than 40 classes that look messy, but are actually very regular and closely related to each other. The Java I0 stream has more than 40 classes derived from the following four abstract class base classes.
- InputStream/Reader: Base class for all input streams. The former is a byte InputStream and the latter is a character InputStream.
- OutputStream/Writer: Base class for all output streams, the former byte stream and the latter character stream.
Classification Structure Diagram by Operation Mode:
Classification Structure Diagram by Operation Object:
Why have a stream of characters when you have a stream of bytes?
The essence of the question is: the minimum storage unit of information, whether it is a file, read or write, or a network, is a byte. So why do I/O stream operations have to be divided into byte stream operations and character stream operations?
Answer: The character stream is generated by the Java Virtual Machine (JVM) converting the bytes. The problem is that the process is very time consuming, and if we don’t know the encoding type, it is easy to get garbled. Therefore, the I/O stream simply provides a direct manipulation of the character interface, which is convenient for us to stream the character. A byte stream is better for audio files, pictures, and other media files, and a character stream if characters are involved.
4. Reference
- https://stackoverflow.com/que…
- https://www.educba.com/oracle…
- https://stackoverflow.com/que… Basic concepts and common sense