Let’s take a look at the mind map for this article, and I’ll focus on the following.
Let’s start our article.
Java overview
What is Java?
Java is a programming language and computing platform first released by Sun Microsystems in 1995. Programming languages are relatively easy to understand, but what are computing platforms?
A computing platform is the environment in which applications (software) run on a computer, both hardware and software. A general system platform includes a computer’s hardware architecture, operating system, and runtime library.
Java is fast, secure and reliable. From laptops to data centers, from game consoles to scientific supercomputers, from mobile phones to the Internet, Java is everywhere! There are three main versions of Java
- JavaSE(J2SE)(Java Platform Standard Edition)
- JavaEE(J2EE)(Java 2 Platform,Enterprise Edition, Java Platform Enterprise Edition)
- JavaME(J2ME)(Java 2 Platform Micro Edition)
The characteristics of the Java
- Java is a door
object-oriented
Programming language
What is object orientation? Object Oriented is a software development idea. It is an abstraction of the real world, and object orientation organizes related data and methods into a holistic view.
The opposite of that is process oriented development. What is process oriented? Procedure Oriented is a process – centered programming idea. For example: If you are a student, how many things do you need to do to go to school every day?
Get up, get dressed, wash your face and brush your teeth, eat, go to school. Usually a sequence of actions is performed sequentially.
class student {
void student_wakeUp(a){... }void student_cloth(a){... }void student_wash(a){... }void student_eating(a){... }void student_gotoSchool(a){...}
}
Copy the code
And object orientation can abstract the student, so this example will become
class student(a){
void wakeUp(a){... }void cloth(a){... }void wash(a){... }void eating(a){... }void gotoSchool(a){...}
}
Copy the code
You can perform each action in a different order. That’s characteristic number one.
- Java eliminates the concepts of multiple inheritance, Pointers, and memory management that are difficult to understand in C++. There is no need to manually manage the life cycle of an object, which is characteristic two.
- Java language has two characteristics of powerful and easy to use, now enterprise development, rapid and agile development, especially the emergence of various frameworks, make Java become more and more popular a language. This is characteristic number three.
- Java is a static language. A static language is one in which data types are known at compile time, checked for correctness before execution, and cannot be changed once they are determined, as in this example.
public void foo(a) {
int x = 5;
boolean b = x;
}
Copy the code
Static languages include Pascal, Perl, C/C++, JAVA, C#, Scala, etc.
In contrast, dynamic languages do not have any specific situation where you need to specify the type of a variable, the data type determined at run time. Lisp, Perl, Python, Ruby, JavaScript, etc.
From a design point of view, all languages are designed to translate human-readable code into machine instructions. Dynamic languages are designed to allow programmers to code more efficiently, so you can use less code to implement features. Static language design is designed to make hardware execution more efficient, so programmers need to write accurate code to make your code execute as quickly as possible. From this point of view, static languages are more efficient and faster than dynamic languages. This is characteristic four.
- Java is platform independent and portable
Java has a famous slogan: Write once, run Anywhere. Write once, run anywhere. Why is Java able to make this kind of noise? The core is the JVM. We know that a lot of details are hidden between computer applications and hardware, and they rely on the operating system for scheduling and coordination between them. The rough architecture is as follows
Then with Java applications, the JVM architecture becomes the following
Java is cross-platform, and compiled Java programs can run on any platform with a JVM. You can write code on Windows and run it on Linux. How do you do that?
First you need to write Java code in your application;
Compile Java code into.class files using Eclipse or Javac;
Then type your.class file into a.jar file;
Then your.jar file will run on Windows, Mac OS X, and Linux. Different operating systems have different JVM implementations, so there is no need to compile your Java code again when switching platforms. This is characteristic number five.
- Java can easily implement multithreading
Java is a high-level language, and high-level languages shield users from many of the low-level implementation details. For example, how Java implements multithreading. From the point of view of the operating system, there are several main ways to achieve multithreading
Implement multithreading in user space
Implement multithreading in kernel space
Mix implementation threads in user and kernel space
In my opinion, Java should be multithreaded in user space, and the kernel is unaware of the existence of multithreading in Java. This is characteristic six.
- Java has high performance
The code we write, compiled by the JavAC compiler and called bytecode, is converted into machine code by an interpreter embedded in the JVM, which is interpreted execution, a less efficient process. However, some JVM implementations such as Hotspot JVM provide a Just-in-time (JIT) compiler, also known as a dynamic compiler . The JIT can compile hot code into machine code at run Time, which is more efficient. So Java is more than just a language to explain execution. This is characteristic seven.
- The Java language is robust
Java’s strong typing mechanism, exception handling and automatic garbage collection are important guarantees for the robustness of Java programs. This is an important difference between Java and C. This is characteristic eight.
- Java makes it easy to develop distributed projects
Java language supports the development of Internet applications. There is NET API in Java, which provides class libraries for network application programming, including URL, URLConnection, Socket, ServerSocket and so on. Java’s RMI (Remote method activation) mechanism is also an important means of developing distributed applications. This is characteristic nine.
Java Development environment
JDK
The Java Development Kit (JDK), known as the Java Development Kit or Java Development tool, is a program Development environment for writing Java Applet small programs and applications. The JDK is the core of Java, including the Java Runtime Environment (Java Runtime Environment), some Java tools, and Java’s core class libraries (Java apis).
We can take a close look at this Diagram, which includes almost all concepts in Java. I use JDK1.8. If you click on the Description of Java Conceptual Diagram, you can find that it contains all descriptions of Java
Oracle provides two implementations of the Java platform, the Java Development Standard Toolkit (JDK) and the Java Runtime Environment (JRE). The JDK has much more functionality than the JRE.
JRE
The JRE is a runtime environment and the JDK is a development environment. So you need the JDK to write Java programs, and you need the JRE to run Java programs. The JDK already includes the JRE, so as long as the JDK is installed, you can edit Java programs and run them normally. However, because the JDK contains a lot of non-runtime content and takes up a lot of space, it is not necessary to install the JDK to run ordinary Java programs, but only the JRE can be installed.
Java development environment configuration
There is no more to this place, there are many tutorial configuration materials available online.
Basic Java Syntax
After configuring the Java development environment and downloading Java development tools (Eclipse, IDEA, etc.), you are ready to write Java code. Since this article is to comb through the Java architecture from scratch, it is necessary to start with the basic concepts.
The data type
In Java, there are only four types and eight types of data types
- Integer types: byte, short, int, and long
Byte is a byte. 1 byte equals 8 bits. The default byte value is 0.
Short takes up two bytes (16 bits). 1 short = 16 bits, which also defaults to 0.
1 int = 32 bits, default is 0;
Long takes up eight bytes, that is, 64 bits, 1 long = 64 bits, default is 0L;
So the size of the integer is long > int > short > byte
- floating-point
Floating-point types have two data types: float and double
1 float = 32 bits. The default value is 0.0f.
1 double = 64 bits. Default value: 0.0d;
- character
The char type is a single 16-bit Unicode character with a minimum value of \u0000 (0) and a maximum value of \ uFFFF (65535). The char data type can store any character, such as char A = ‘a’.
- The Boolean
Boolean refers to Boolean. Boolean has only two values, true or false, representing only one bit. The default value is false.
The above X bits refer to the memory usage.
Basic grammar
- Case sensitive: Java is a case-sensitive language. For example, Hello is different from Hello, which is the Java string representation
- Class name: For all classes, the first letter should be capitalized, e.g
MyFirstClass
- Package name: The package name should be lowercase as much as possible, for example
my.first.package
- Method name: The first letter of the method name must be lowercase and each subsequent letter must be uppercase, for example
myFirstMethod()
The operator
Operators are special symbols used for mathematical functions, some types of assignment statements, and logical comparisons. Let’s take Java as an example to look at operators.
- The assignment operator
The assignment operator is represented by the operator =, which means to copy the value to the right of the = sign to the left. The value on the right can be any constant, variable, or expression, but the value on the left must be an explicit, defined variable. So int a is equal to 4.
For objects, however, it is not the value of the object that is copied, but the reference to the object, so if you copy an object to another object, you are actually assigning a reference to one object to another object.
- Arithmetic operator
Arithmetic operators are similar to numerical calculations in mathematics
Arithmetic operators need to be aware of is the priority problem, when there are multiple operators in an expression, the priority order of operator determines the calculation order of the simplest rule is first, then add and subtract, (the) highest priority, there is no need to remember all the priority order of uncertain with () directly.
- Increment and decrement operators
This does not explain the text, the explanation is not as clear as looking at examples directly
int a = 5;
b = ++a;
c = a++;
Copy the code
- Comparison operator
Comparison operators are used to compare variables in a program, between variables and arguments, and other types of information.
The result of the comparison operator is Boolean. The result of the operation is true if the relation of the operator is true, false otherwise. There are six comparison operators, which are usually used in conditional statements.
- Logical operator
There are three main types of logical operators, and, or, and not
Here is the true/false symbol table for the logical operators
- Bitwise operators
Bitwise operators are used to operate on each bit in the basic type of integers, that is, binary bits. Bitwise operators perform Boolean algebra on the corresponding bits of the two arguments and ultimately produce a result.
If the two sides of the comparison are numbers, the comparison becomes bitwise.
Bitwise AND: The operation (AND) is performed bitwise. The result is 1 only if the middle bit of both operands is 1. Otherwise, the result is 0. You need to first convert both sides of the comparison to binary and then compare each bit
Bitwise OR: To operate OR (OR) by bitwise, so that if either of the two bits is 1, the result is 1, otherwise it is 0.
Bitwise non: XOR (XOR) performed by bit, resulting in 1 if the bit is 0 and 0 if the bit is 1.
Bitwise xor: The reverse operation (NOT) is performed bitwise. If the bits of two operands are the same, the result is 0; if they are different, the result is 1.
- Shift operator
The shift operator is used to move the operand in a direction (left or right) by a specified number of bits.
- Ternary operator
Ternary operators are similar to if… else… This operator has the syntax: conditional expression? Expression 1: expression 2. The position in front of the question mark is the condition to determine if the result is Boolean. Expression 1 is called when it is true and expression 2 is called when it is false.
Java executes the control flow
Control flow in Java is actually the same as C. In Java, flow control involves if-else, while, do-while, for, return, break and the selection statement switch. Let’s analyze this
Conditional statements
Conditional statement Different statements can be executed according to different conditions. Includes if conditional statements and switch multi-branch statements.
If conditional statement
The if statement can independently determine the result of an expression, indicating the execution result of the expression, for example
int a = 10;
if(a > 10) {return true;
}
return false;
Copy the code
if… Else conditional statement
An if statement can also be used with an else, and usually behaves as if one condition is met, and another if not.
int a = 10;
int b = 11;
if(a >= b){
System.out.println("a >= b");
}else{
System.out.println("a < b");
}
Copy the code
The expression in () after if must be Boolean. If true, the compound statement after if is executed. If false, the compound statement after else is executed.
if… Else if multi-branch statement
The above if… Else is a single and two branch judgment. If there are multiple criteria, use if… else if
int x = 40;
if(x > 60) {
System.out.println("X is greater than 60.");
} else if (x > 30) {
System.out.println("X is greater than 30 but less than 60.");
} else if (x > 0) {
System.out.println("X is greater than 0 but less than 30.");
} else {
System.out.println("X is less than or equal to 0.");
}
Copy the code
Switch Multi-branch statement
Than a * * the if… A more elegant approach to the else if ** statement is to use the switch multi-branch statement, as shown below
switch (week) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
case 4:
System.out.println("Thursday");
break;
case 5:
System.out.println("Friday");
break;
case 6:
System.out.println("Saturday");
break;
case 7:
System.out.println("Sunday");
break;
default:
System.out.println("No Else");
break;
}
Copy the code
Looping statements
A loop statement is an operation that executes an expression repeatedly under certain conditions until it satisfies the requirements of a loop statement. The loop statements used are **for, do… While (), while **,
While loop statement
The while loop uses a condition to control whether to continue executing the statement repeatedly. The format of the while loop statement is as follows
while(Boolean value){expression}Copy the code
It means that when (Boolean) is true, the following expression is executed, and when Boolean is false, the loop is terminated. Boolean is also an expression, such as
int a = 10;
while(a > 5){
a--;
}
Copy the code
do… The while loop
While with the do… The only difference in the while loop is do… The while statement is executed at least once, even if the expression is false the first time. In the while loop, if the condition is false the first time, the statement is not executed at all. In practice, while is better than do… While is more widely used. Its general form is as follows
int b = 10;
// do···while loop
do {
System.out.println("b == " + b);
b--;
} while(b == 1);
Copy the code
For loop
The for loop is the most common type of loop that is initialized before the first iteration. It has the following form
forInitialization; Boolean expression; Step by step) {}Copy the code
Boolean expressions are tested before each iteration. If the result is false, the code following the for statement is executed; At the end of each loop, the next loop is executed with the values of the step.
Comma operator
The one not to be ignored here is the comma operator, which is used only in Java for loop control statements. In the initialization part of an expression, you can use a series of comma-separated statements; With the comma operator, you can define multiple variables within a for statement, but they must have the same type
for(int i = 1; j = i +10; i <5; i++, j = j *2) {}Copy the code
For-each statements
A more concise way to iterate over arrays and collections was introduced in Java JDK 1.5, called the for-each statement, as shown in the following example
int array[] = {7.8.9};
for (int arr : array) {
System.out.println(arr);
}
Copy the code
Jump statements
In the Java language, there are three types of jump statements: break, continue, and return
Break statement
The break statement we have seen in switch is used to terminate the loop. In fact, the break statement is used in the for, while, do···while loop to force out of the current loop, for example
for(int i = 0; i <10; i++){if(i == 5) {break; }}Copy the code
The continue statement
A continue can also be placed in a loop statement. It has the opposite effect of a break statement and is used to execute the next loop rather than exit the current loop, as in the example above
for(int i = 0; i <10; i++){ System.out.printl(" i = " + i );
if(i == 5){
System.out.printl("continue ... ");
continue; }}Copy the code
Return statement
A return statement can return from a method and give control to the calling statement.
public void getName(a) {
return name;
}
Copy the code
object-oriented
Let’s talk about object-oriented thinking, which has gradually replaced procedural thinking. Java is an object-oriented high-level programming language, and object-oriented languages have the following characteristics
-
Object oriented is a common idea, which is in line with people’s thinking habits.
-
Object orientation can simplify complex business logic and enhance code reuse.
-
Object-oriented has the characteristics of abstraction, encapsulation, inheritance, polymorphism and so on.
Object-oriented programming languages are: C++, Java, C# and so on.
So you must be familiar with object-oriented thinking to write Java programs.
A class is also an object
Now we come to know a new concept of object oriented – class, what is the class, it was quite a series of abstract objects, such as books, class rather then the cover of the book, most object-oriented languages use the class to define a class, it tells you define what kind of objects are inside it, we usually use the following to define the class
class ClassName {
// body;
}
Copy the code
There is a new concept involved in the code snippet //, which we will talk about later. Above, you declared a class. Now, you can use new to create this object
ClassName classname = new ClassName();
Copy the code
In general, the naming of classes follows the hump rule, which is defined as follows
Camel-Case is a set of naming rules (conventions) used in computer programming. As the name CamelCase implies, it refers to the use of a mixture of upper and lower case letters to form variable and function names. In order to make it easier for programmers to communicate their code among peers, they often adopt uniform and readable naming methods.
Object creation
In Java, everything is an object. Although everything is considered an object, you are manipulating a reference to an object. Here’s a good analogy: you can think of car keys and cars as a combination of object references and objects. When you want to drive, you first need to take out the car keys and click the lock option. When parking, you need to click lock to lock the car. The car key is equivalent to reference, the car is the object, by the car key to drive the car lock and unlock. Also, even if there is no car, the car key is a separate entity, that is, you have an object reference, but you don’t necessarily need an object associated with it, i.e
Car carKey;
Copy the code
This is a reference, not an object, but if you want to use the s reference, an exception will be returned telling you that you need an object to associate with the reference. It is safe to assign an object to an object when you create an object reference.
Car carKey = new Car();
Copy the code
In Java, once a reference is created, you want it to be associated with a new object, often using the new operator to do this. New means, give me a new date. If you don’t want a blind date, just make yourself a new date. I wish you happiness in your next life.
Properties and methods
One of the most basic elements of a class is that it has properties and methods.
An attribute, also known as a field, is an important part of a class and can be an object of any type or a basic data type. For example, under the
class A{
int a;
Apple apple;
}
Copy the code
Classes should also include methods, which represent ways of doing something. Methods are just functions, but Java has a habit of calling them methods. This term also reflects the concept of object orientation.
The basic composition of a method consists of a method name, parameters, return values, and the method body, as shown in the following example
public int getResult(a){
// ...
return 1;
}
Copy the code
Where getResult is the method name, () is the parameter received by the method, and return is the return value of the method. Note that the return value of the method must be the same as the parameter type of the method. There is a special argument type, void, to indicate that the method returns no value. The code snippet that {} contains is called the method body.
A constructor
In Java, there is a special class of methods called constructors, also known as constructors, constructors, etc. In Java, you ensure that every object is initialized by providing this constructor. The constructor can only be called once at object creation time, ensuring that the object is initialized. A constructor is special. It has no parameter type or return value, its name must be the same as the class name, and there can be more than one constructor. Here is an example constructor
class Apple {
int sum;
String color;
public Apple(a){}
public Apple(int sum){}
public Apple(String color){}
public Apple(int sum,String color){}}Copy the code
The Apple class has no argument types or return values. It has multiple methods with the same name as Apple, and the argument list varies from Apple to Apple. This is a bit polymorphic, as we’ll see later. With the constructor defined, we are ready to create the Apple object.
class createApple {
public static void main(String[] args) {
Apple apple1 = new Apple();
Apple apple2 = new Apple(1);
Apple apple3 = new Apple("red");
Apple apple4 = new Apple(2."color"); }}Copy the code
As shown above, we defined four Apple objects and called four different Apple constructors, where the constructor without any arguments is called the default constructor, i.e
Apple apple1 = new Apple();
Copy the code
If no constructor is defined in the class, the JVM automatically generates one for you, as follows
class Apple {
int sum;
String color;
}
class createApple {
public static void main(String[] args) {
Apple apple1 = newApple(); }}Copy the code
The above code does not compile errors because the Apple object contains a default constructor.
The default constructor is also called a default constructor or a no-parameter constructor.
One thing to note here is that even though the JVM will add a constructor with no arguments by default, if you define any constructor manually, the JVM will no longer provide you with a default constructor. You must specify it manually or you will get a compilation error.
The error is that the Apple constructor with an int must be supplied, and the default no-argument constructor is not allowed.
Method overloading
An important concept in Java is method overloading, which is a different representation of a class name. We talked about constructors, but constructors are a type of overload. The other is method overloading
public class Apple {
int sum;
String color;
public Apple(a){}
public Apple(int sum){}
public int getApple(int num){
return 1;
}
public String getApple(String color){
return "color"; }}Copy the code
As shown above, there are two ways to overload: the Apple constructor and the getApple method.
But this raises the question: how does Java know which method you’re calling if there are several of the same names? One thing to remember here is that each overloaded method has a unique argument list. It includes the type, order and number of parameters, etc. Meeting one factor constitutes the necessary condition of overloading.
Remember the following overload conditions
-
The method names must be the same.
-
Parameter lists must be different (number, type, order of parameter types, etc.).
-
Methods can have the same or different return types.
-
The mere fact that the return type is different is not enough to be a method overload.
-
Overloading occurs at compile time because the compiler can choose which method to use based on the type of the parameter.
Method rewriting
Method overwriting and overloading have similar names, but are completely different things. Method overrides are described between subclasses and superclasses. And an overload is in the same class. For example:
class Fruit {
public void eat(a){
System.out.printl('eat fruit'); }}class Apple extends Fruit{
@Override
public void eat(a){
System.out.printl('eat apple'); }}Copy the code
The code above describes the overwritten code, and as you can see, the method in the Apple subclass has the same name as the method in the Fruit parent class, so we can deduce the overwritten principle
- The overridden method must be identical to the parent class, including the return value type, method name, and argument list.
- Override methods can be used
@Override
Annotate to mark - Overriding methods in subclasses cannot have less access than methods in their parent classes.
Initialize the
Class initialization
The Car constructor is initialized using the new keyword. The Car constructor is initialized using the new keyword. The Car constructor is initialized using the new keyword
class Car{
public Car(a){}}Copy the code
This parameterless constructor can be hidden and added automatically by the JVM. That is, the constructor ensures class initialization.
Member initialization
Java tries to ensure that every variable is initialized before it is used, and initialization involves two types of initialization.
-
One is the initialization of fields specified by the compiler by default, the initialization of primitive data types
One is the initialization of other object types. A String is also an object with an initial value of NULL, including a wrapper class for the primitive type.
-
One is to specify the initialization of a value, for example
int a = 11
Copy the code
That is, specify that the initial value of a is not 0, but 11. The same is true for other primitive and object types.
Constructor initialization
You can use constructors to initialize certain methods and certain actions to determine initial values, for example
public class Counter{
int i;
public Counter(a){
i = 11; }}Copy the code
Using the constructor, we can initialize the value of I to 11.
Initialization sequence
First, let’s look at the initialization sequence we need to discuss
-
Static properties: Properties defined at the beginning of static
-
Static method block: a block of code wrapped in static {}
-
Common properties: properties that are not static defined
-
Normal method block: code block wrapped around {}
-
Constructor: a method with the same class name
-
Method: Common method
public class LifeCycle {
// Static attributes
private static String staticField = getStaticField();
// Static method block
static {
System.out.println(staticField);
System.out.println("Static method block initialization");
}
// Common attributes
private String field = getField();
// Normal method block
{
System.out.println(field);
}
// constructor
public LifeCycle(a) {
System.out.println("Constructor initialization");
}
public static String getStaticField(a) {
String statiFiled = "Static Field Initial";
return statiFiled;
}
public static String getField(a) {
String filed = "Field Initial";
return filed;
}
/ / the main function
public static void main(String[] argc) {
newLifeCycle(); }}Copy the code
The execution of this code reflects the order in which it was initialized
Static property initialization static method block initialization common property initialization common method block initialization constructor initialization
Array initialization
An array is a sequence of objects or primitive-type data of the same type wrapped together with an identifier name. Arrays are defined using the square bracket subscript operator [].
This is how arrays are defined
int[] a1;
/ / or
int a1[];
Copy the code
The meaning of both formats is the same.
- Int array[4] = {1,2,3,4};
- Int array[4] = {1,2};
- Int array[] = {1,2};
Variable argument list
One popular use of arrays in Java is mutable parameters, which are defined as follows
public int add(int. numbers){
int sum = 0;
for(int num : numbers){
sum += num;
}
return sum;
}
Copy the code
You can then make variadic calls in the following ways
add(); // Do not pass parameters
add(1); // Pass a parameter
add(2.1); // Pass multiple arguments
add(new Integer[] {1.3.2}); // Pass the array
Copy the code
Object destruction
Although the Java language is based on C++, an important feature of it and C/C++ is that it does not need to manually manage object destruction. There is a point mentioned in the famous book Understanding the Java Virtual Machine
In Java, we no longer need to manage object destruction manually; it is managed and destroyed by the Java Virtual machine. Although we don’t need to manage objects manually, you do need to know the concept of object scope.
Object scope
J Most languages have the concept of scope. A scope determines the visibility and lifetime of its internally defined variable names. In C, C++, and Java, scope is usually determined by the position of {}, for example
{
int a = 11;
{
int b = 12; }}Copy the code
The a variable is valid in both {} scopes, while the value of the B variable is valid only in its own {}.
Although scope exists, this is not allowed
{
int x = 11;
{
int x = 12; }}Copy the code
This is ok in C/C++, but not allowed in Java because the Java designers believe it can lead to clutter.
# # # this and super
This and super are both Java keywords
This can call methods, call properties, and point to the object itself. There are three common ways to use this in Java: to refer to the current object
public class Apple {
int i = 0;
Apple eatApple(a){
i++;
return this;
}
public static void main(String[] args) {
Apple apple = newApple(); apple.eatApple().eatApple(); }}Copy the code
This code is more subtle, subtle in where, I an eatApple() method can be called many times, you can continue to call in the back, this is very magical, why? In fact, this is the problem. I added a return value of this to the eatApple method, which means that any object that calls the eatApple method returns itself.
This can also modify attributes, most commonly in constructors, as shown below
public class Apple {
private int num;
public Apple(int num){
this.num = num;
}
public static void main(String[] args) {
new Apple(10); }}Copy the code
The main method passes an int of 10, which represents the number of apples, and assigns that number to the num global variable. So the value of num is now 10.
This can also be used with constructors to act as a global keyword
public class Apple {
private int num;
private String color;
public Apple(int num){
this(num,"Red");
}
public Apple(String color){
this(1,color);
}
public Apple(int num, String color) {
this.num = num;
this.color = color; }}Copy the code
You’ll notice that the above code doesn’t use this, but this(argument). It’s equivalent to calling some other constructor and passing in arguments. One thing to note here: this() must be on the first line of the constructor or the compiler will fail
If you think of this as a reference to itself, then super is a reference to the parent class. The super keyword, just like this, you can use super. Object to reference a member of the parent class, as follows
public class Fruit {
int num;
String color;
public void eat(a){
System.out.println("eat Fruit"); }}public class Apple extends Fruit{
@Override
public void eat(a) {
super.num = 10;
System.out.println("eat " + num + " Apple"); }}Copy the code
You can also use super to call the constructor of the parent class, but I won’t give you an example here.
Here’s a comparison of this and super for you.
Access control permission
Access control permissions are also called encapsulation, which is one of the three main features of object orientation. I used to ignore encapsulation in the process of learning, thinking that this is not an access modifier, why is it a necessary condition of the three features? I later learned that if a trusted subordinate is hiding a bug from you, you don’t know it.
Access control permissions are, at their core, visible only to classes that need them.
There are four types of member access permissions in Java: public, protected, default, and private. Their visibility is as follows
inheritance
Inheritance is an integral part of all OOP(Object Oriented Programming) and Java languages. As soon as we create a class, we implicitly inherit from the Object parent, but we don’t specify it. If you specify a parent class, then you inherit from the parent class, and your parent class inherits from Object.
The inheritance keyword is extends, as shown in the figure above. If extends is used to specify inheritance, then we can say Father is the parent class and Son is the subclass, as shown in the code below
class Father{}
class Son extends Father{}
Copy the code
The two sides of the succession have some common characteristics
class Father{
public void feature(a){
System.out.println("Traits of a father."); }}class Son extends Father {}Copy the code
If Son does not implement its own method, the default is to use the parent feature method. If the subclass implements its own feature method, it is equivalent to rewriting the feature method of its parent class, which is also the rewriting mentioned above.
polymorphism
Polymorphism refers to multiple different manifestations of the same behavior. Means that the same method of a class instance (object) has different representations in different situations. Encapsulation and inheritance are the basis of polymorphism, that is, polymorphism is just a manifestation.
How to implement polymorphism? There are three necessary and sufficient conditions for the realization of polymorphism
- inheritance
- Override the parent class method
- A superclass reference points to a subclass object
Take this code for example
public class Fruit {
int num;
public void eat(a){
System.out.println("eat Fruit"); }}public class Apple extends Fruit{
@Override
public void eat(a) {
super.num = 10;
System.out.println("eat " + num + " Apple");
}
public static void main(String[] args) {
Fruit fruit = newApple(); fruit.eat(); }}Copy the code
You can see the magic in the main method, Fruit Fruit = new Apple(), where an object of type Fruit refers to a reference to an Apple object, which is essentially polymorphic -> parent refers to a subclass object, because Apple inherits from Fruit, And rewrote the eat method, so that it could represent a variety of states.
combination
Composition is easy to understand, simply placing object references in a new class. Composition is also a way to improve class reusability. If you want classes to have more extensibility, you need to remember to use composition more than inheritance.
public class SoccerPlayer {
private String name;
private Soccer soccer;
}
public class Soccer {
private String soccerName;
}
Copy the code
SoccerPlayer references the Soccer class to call properties and methods in Soccer.
Composition and inheritance are different, and the main differences are as follows.
The debate about inheritance and combination is fruitless, as long as they give play to their strengths and advantages. In general, combination and inheritance are also good brothers that can be used together.
The agent
In addition to inheritance and composition, another relational model worth exploring is called proxy. The general description of A proxy is that A wants to call A method of class B, but A does not call it directly. A creates A proxy of B objects in its own class, and then the proxy calls B methods. For example:
public class Destination {
public void todo(a){
System.out.println("control..."); }}public class Device {
private String name;
private Destination destination;
private DeviceController deviceController;
public void control(Destination destination){ destination.todo(); }}public class DeviceController {
private Device name;
private Destination destination;
public void control(Destination destination){ destination.todo(); }}Copy the code
upcasting
Upward transformation represents the relationship between the parent class and the child class. In fact, there is not only upward transformation between the parent class and the child class, but also downward transformation, and their transformation ranges are different
upcasting
: By converting a subclass object (small scope) to a superclass object (large scope), this conversion is automatic and not mandatory.Downward transition
: instantiates a child object (small) from a parent object (large range). This conversion is not automatic and must be specified forcibly.
static
Static is used to modify member variables and methods. Static is used to call methods/variables without creating objects.
- Member variables declared static are static member variables and also class variables. Class variables have the same life cycle as classes and remain in effect throughout application execution.
static String name = "cxuan";
Copy the code
- Methods that use the static modifier are called static methods, and static methods can use the class name directly. Method name to call. Since static methods can be accessed directly without relying on any object, there is no such keyword for static methods; instance variables always have this. Non-static member variables and non-static methods of a class cannot be accessed in a static method,
static void printMessage(a){
System.out.println("cxuan is writing the article");
}
Copy the code
In addition to modifying properties and methods, static has the ability to use static code blocks for class initialization operations. To improve the performance of the program.
public class StaicBlock {
static{
System.out.println("I'm A static code block"); }}Copy the code
Because static code blocks execute as the class is loaded, many times initialization operations that only need to be done once are placed in static code blocks.
final
Final means final, final, and it can modify classes, properties, and methods.
- When final decorates a class, it indicates that the class cannot be inherited. Member variables ina final class can be set to final if necessary, but be aware that all member methods ina final class are implicitly specified as final methods.
- Final decorates a method to indicate that the method cannot be overridden by any subclass, so make the method final only if you want to explicitly forbid the method to be overridden ina subclass.
- Final modifies variables into two situations. One modifies basic data types, indicating that the value of the data type cannot be modified. One is to decorate a reference type to indicate that it can no longer point to another object after it has been initialized.
Interfaces and abstract classes
interface
An interface is an external convention and standard. Take the operating system as an example. Why is there an operating system? In order to shield the difference between software complexity and hardware simplicity, a unified standard will be provided for software.
In the Java language, interfaces are represented by the interface keyword. For example, we can define an interface as follows
public interface CxuanGoodJob {}
Copy the code
For example, if we define an interface to cxuanggood job, then you can define inside it the things that CXuan does well, such as cXuan writes good articles.
public interface CxuanGoodJob {
void writeWell(a);
}
Copy the code
Some interface characteristics are implied here:
interface
Interface is a completely abstract class, it does not provide any method implementation, only method definition.- There are only two types of access modifiers that can be used in an interface
public
It is visible to the entire project; One is thedefault
By default, it only has package access rights. - An interface provides only the definition of a method. An interface is not implemented, but an interface can be implemented by other classes. That is, the class that implements the interface needs to provide implementations of methods that the implementation interface uses
implements
An interface can have multiple implementations.
class CXuanWriteWell implements CxuanGoodJob{
@Override
public void writeWell(a) {
System.out.println("Cxuan write Java is vary well"); }}Copy the code
- The interface can’t be instantiated, so there can’t be any constructors in the interface, and if you define constructors, the compiler will fail.
- An implementation of an interface must implement all methods of the interface, otherwise it must be defined as
An abstract class
That’s what we’re going to talk about
An abstract class
Abstract class is a class with weaker abstraction ability than interface. In Java, abstract class is represented by the abstract keyword. If the interface is described as a dog species, then the abstract class can be described as white and small, while the implementation class can be concrete, such as Pomerangs, teddies, etc. You can define an abstract class as follows
public interface Dog {
void FurColor(a);
}
abstract class WhiteDog implements Dog{
public void FurColor(a){
System.out.println("Fur is white");
}
abstract void SmallBody(a);
}
Copy the code
In an abstract class, it has the following characteristics
-
If there are abstract methods in a class, the class must be abstract. That is, methods decorated with the keyword abstract must be abstract methods, and classes with abstract methods must be abstract classes. There are only method concrete implementations in implementation class methods.
-
Abstract classes do not have to have only abstract methods. Abstract classes can also have concrete methods, and you can choose whether to implement those methods or not.
-
You can define constructors, abstract methods, ordinary properties, methods, static properties, and static methods in abstract classes, where the constraints are not as strict as in interfaces
-
Abstract classes, like interfaces, cannot be instantiated; instantiation can only instantiate concrete classes
abnormal
Exceptions are a common occurrence in programs, and the best time to detect errors is during compilation, before you try to run the program. However, not all errors are found at compile time. Some NullPointerExceptions and ClassNotFoundException are not found at compile time. These are RuntimeExceptions. These exceptions are often discovered at run time.
Java.lang.Error: java.lang.Error: java.lang.Error: java.lang.Error: java.lang.
Know the Exception
Exception, located in the java.lang package, is a top-level interface that inherits from the Throwable class. The Exception class and its subclasses are both Throwable and reasonable conditions for applications.
Before you get to Exception, it’s important to understand what Throwable is.
What is a Throwable
The Throwable class is the parent class of all errors and exceptions in the Java language. Only classes that inherit from Throwable or subclasses of Throwable can be thrown. Alternatively, classes with the @throw annotation in Java can also be thrown.
In the Java specification, non-checked and checked exceptions are defined as follows:
The unchecked exception classes are the run-time exception classes and the error classes.
The checked exception classes are all exception classes other than the unchecked exception classes. That is, the checked exception classes are
Throwable
and all its subclasses other thanRuntimeException
and its subclasses andError
and its subclasses.
That is, all exceptions except RuntimeException and its subclasses, and Error and its subclasses are checkedException.
So, according to this logical relationship, we can classify and analyze Throwable and its subclasses
As you can see, Throwable is at the top of the list of exceptions and errors. When we look at the Throwable class, there are many methods and attributes. We’ll discuss only a few of the more common ones
// Returns the details of the exception thrown
public string getMessage(a);
public string getLocalizedMessage(a);
// Returns a brief description of when the exception occurred
public public String toString(a);// Prints exception information to the standard output stream
public void printStackTrace(a);
public void printStackTrace(PrintStream s);
public void printStackTrace(PrintWriter s)
// Record the current state of the stack frame
public synchronized Throwable fillInStackTrace(a);
Copy the code
In addition, because Throwable’s parent class is also Object, common methods include getClass() and getName() methods that inherit from its parent class.
Common Exception
Back to Exception, now that you know that Exception’s parent class is Throwable and that Exception has two types of exceptions: RuntimeException; One is CheckedException, both of which should be caught.
Below is a list of common exceptions in Java and their classification. The interviewer may also ask you to name a few common exceptions and categorize them
RuntimeException
UncheckedException
Java keywords associated with Exception
So how do these exceptions work in Java? Throws, throw, try, finally, and catch are the keywords in Java
Throws and throw
In Java, an exception is an object that can be thrown by a programmer or an application. Throw exceptions must be defined using throws and throws statements.
Throws and throws are usually paired, for example
static void cacheException(a) throws Exception{
throw new Exception();
}
Copy the code
A throw statement is used in a method body to indicate that an exception is thrown and is handled by a statement in the method body. Throws a throws exception, which is handled by the caller of the method.
Throws throws Throws throws throws throws of this type so that its caller knows to catch the exception. A throw is the action of specifically throwing an exception, so it throws an exception instance.
Try, finally, catch
Try… try… try… The catch, try… Finally, try… catch… The finally.
try… Catch represents a catch for an exception that a piece of code might throw, as follows
static void cacheException(a) throws Exception{
try {
System.out.println("1");
}catch(Exception e){ e.printStackTrace(); }}Copy the code
try… Finally means that a piece of code will be executed regardless of the situation
static void cacheException(a) throws Exception{
for (int i = 0; i < 5; i++) {
System.out.println("enter: i=" + i);
try {
System.out.println("execute: i=" + i);
continue;
} finally {
System.out.println("leave: i="+ i); }}}Copy the code
try… catch… Finally is the same, indicating that after the exception is caught, the code logic in finally is passed.
What is the Error
An Error is an Error that the program cannot handle and indicates a serious problem in running the application. Most errors have nothing to do with what the code writer is doing, and instead represent problems with the JVM (Java Virtual Machine) while the code is running. These errors are not detectable because they are outside the control and processing capabilities of the application and are mostly conditions that are not allowed to occur while the program is running, such as OutOfMemoryError and StackOverflowError exceptions. The Java memory model, JDK1.7, needs to be introduced.
In the Java memory model above, only the program counter is the area where OutOfMemoryError does not occur. The program counter controls the branch, loop, jump, exception handling, and thread recovery of computer instructions. And program counters are per-thread private.
Thread private: Represents an area of memory that is stored independently of each other by threads.
If the application executes Java methods, this counter records the address of the virtual machine’s bytecode instructions; If the Native method is being executed, this counter value is null (Undefined).
In addition to program counters, other areas: Method Area, VM Stack, Native Method Stack, and Heap are all areas where OutofMemoryErrors can occur.
-
Virtual machine stack: StackOverflowError occurs if the thread requests a stack depth larger than the virtual machine stack allows. An OutOfMemoryError occurs if the virtual machine cannot allocate sufficient memory for dynamic scaling.
-
The local method stack is the same as the virtual machine stack
-
Heap: The Java heap can be physically discontinuous and logically continuous, just like our disk space, and an OutOfMemoryError will be thrown if there is no memory in the heap for instance allocation and the heap cannot be extended.
-
Method area: OutOfMemoryError is thrown when the method area cannot meet memory allocation requirements.
In Java, you can think of exceptions as a mechanism to improve the robustness of your program, so that you can write code that pays attention to these exceptions, or you can’t be a core programmer if you don’t write code that pays attention to these exceptions.
The inner class
Up to now, we only know the definition of a common class, that is, to create a class directly in IDEA.
After completion of the new, you’ll have a class file, the definition of the operation is too simple, in the long run will be boring, we young people need more and more trendy SAO gas spelled, okay, since you mentioned that you use an inner class, this is a useful and SAO gas class, the definition of the definition of the inner class is very simple: You can put the definition of one class inside another class, which is called an inner class.
Inner class is a very useful feature, defined inside the class class that holds the external class references, but for other external invisible, looks like a hidden code mechanism, and the French general, French can communicate and French general, but the enemy outside cannot attack directly to the French ontology.
Let’s talk about how to create inner classes.
Creating an inner class
Defining an inner class is very simple, just define a class directly inside the outer class, as shown in the following code
public class OuterClass {
private String name ;
private int age;
class InnerClass{
public InnerClass(a){
name = "cxuan";
age = 25; }}}Copy the code
In this code, InnerClass is an InnerClass of the OuterClass. That is, each inner class can inherit an implementation independently, so it doesn’t matter whether the enclosing class already inherits an implementation. This also hides the internal implementation details. The inner class has access to the outer class.
Inner classes can be defined not only inside a class, but also inside a method or scope. This is called a local inner class. In addition, there are anonymous inner classes, which can implement multiple inheritance in Java. Here’s how you define an inner class
-
A class defined in a method (local inner class)Copy the code
-
A class defined in scope inside a method (member inner class)Copy the code
-
An anonymous class that implements the interface (anonymous inner class)Copy the code
-
An anonymous class that extends classes that are not default constructorsCopy the code
-
An anonymous class that performs field initialization operationsCopy the code
-
An anonymous class that implements a construct through instance initializationCopy the code
Since each class produces a.class file that contains all the information about how to create objects of that type, how do you represent information about inner classes? You can use $to represent it, for example OuterClass$innerclass.class.
A collection of
Collections are used so many times in our daily development that you are already familiar with them, but as a qualified programmer, you need to know not only the basic usage of them, but also the source code; You have to understand how it’s designed and implemented, and you have to understand how it’s derived.
In this blog post, we will take a closer look at the family architecture and members of the large Collection framework, and let you know about its design and implementation.
It’s time for this divine map
The first is the Iterator interface
The Iterable interface
Implementing this interface allows an object to become the target of a for-each loop, which enhances the for loop, a syntactic sugar in Java.
List<Object> list = new ArrayList();
for (Object obj: list){}
Copy the code
In addition to objects that implement this interface, arrays can also be iterated through with a for-each loop, as follows:
Object[] list = new Object[10];
for (Object obj: list){}
Copy the code
Other traversal methods
Before JDK 1.8, Iterator had only one method: Iterator
Iterator<T> iterator(a);
Copy the code
The approach to implementing the subinterface creates a lightweight iterator that can safely traverse, remove, and add elements. There’s a fail-fast mechanism involved.
The bottom line is that if you can create iterators to add and remove elements, use iterators to add and remove elements.
Iterators can also be used for traversal
for(Iterator it = coll.iterator(); it.hasNext(); ) { System.out.println(it.next()); }Copy the code
The top interface
Collection is a top-level interface that defines conventions for collections
The List interface is also a top-level interface that inherits the Collection interface and is the parent class of Collection elements such as ArrayList and LinkedList
The Set interface is on the same level as the List interface, and it also inherits the Collection interface. The Set interface provides additional provisions. It provides additional standards for the add, Equals, and hashCode methods.
Queue is one of the three interfaces of a Collection, along with List and Set. Queue is designed to preserve the order in which elements are accessed prior to processing. Queues provide additional insert, read, and check operations in addition to the basic operations of Collection.
The SortedSet interface directly inherits from the Set interface, using Comparable to naturally sort elements or using a Comparator to provide custom collation of elements at creation time. The iterator to set traverses the collection in ascending element order.
A Map is an object that supports key-value storage. A Map cannot contain duplicate keys and maps a maximum of one value to each key. This interface replaces the Dictionary class, which is an abstract class rather than an interface.
ArrayList
ArrayList is an expandable array (dynamic array) that implements the List interface. Its internal implementation is based on arrays. It is defined as follows:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess.Cloneable.java.io.Serializable {... }Copy the code
- ArrayList implements all optional list operations, allowing all elements, including null values. ArrayList also provides a way to store lists internally, which is a complete substitute for Vector, with one exception: ArrayList is not a thread-safe container.
- An ArrayList has a concept of capacity, the capacity of the array is the capacity of the List to store its elements.
- ArrayList is not a thread-safe container. If at least two threads out of multiple threads modify the structure of ArrayList, thread-safe List can be used as an alternative condition, and should be used
Collections.synchronizedList
。
List list = Collections.synchronizedList(newArrayList(...) )Copy the code
- ArrayList has the fail-fast mechanism to detect the failure of ArrayList. Fail-fast, or throwing, can occur when the collection is structurally changed during iteration
ConcurrentModificationException
The exception.
Vector
Vector, like ArrayList, is implemented based on arrays, except that it is a thread-safe container. It simply locks every method inside it, avoiding security problems caused by multiple threads. However, this synchronization method usually requires a high overhead. Accessing elements is much less efficient than ArrayList.
Another point is that ArrayList increases the size of arrays by 50%, while Vector doubles the size of arrays.
LinkedList class
LinkedList is a two-way LinkedList that allows storing any element (including null). Its main features are as follows:
- All LinkedList operations can be bidirectional, indexed to LinkedList operations are traversed from beginning to end, depending on which proximity is the traversal order.
- Note that this implementation is also not thread-safe; if multiple threads concurrently access the list and at least one of them changes the structure of the list, then the list must be externally locked. Or use
List list = Collections.synchronizedList(newLinkedList(...) )Copy the code
Stack
The stack is what we call a last in, first out container. It inherits from the Vector class, providing the usual push and pop operations, a peek method at the top of the stack, an empty method to test if the stack is empty, and a search method to find the distance from the top of the stack.
The first time the stack is created, it contains no elements. A more complete and reliable LIFO stack operation provided by the Deque interface and its implementation should be preferred
Deque<Integer> stack = new ArrayDeque<Integer>()
Copy the code
HashSet
A HashSet is an implementation class of the Set interface, supported by a hash table (in fact, a HashSet is an instance of a HashMap). It does not guarantee the iteration order of the set. This class allows null elements.
- Note that this implementation is not thread-safe. If multiple threads concurrently access a HashSet, and at least one thread modifies the set, an external lock must be performed. Or use
Collections.synchronizedSet()
Method override. - This implementation supports the fail-fast mechanism.
TreeSet
TreeSet is a NavigableSet implementation based on TreeMap. Depending on the constructor used, these elements are sorted using either their natural sorting or the Comparator provided at creation time.
- This implementation provides a log(n) time cost for the basic operations Add,remove, and Contains.
- Note that this implementation is not thread-safe. If multiple threads concurrently access TreeSet and at least one thread modifies the set, an external lock must be performed. Or use
SortedSet s = Collections.synchronizedSortedSet(newTreeSet(...) )Copy the code
- This implementation holds the fail-fast mechanism.
LinkedHashSet class
LinkedHashSet inherited from Set. Let’s take a look at the inheritance system of LinkedHashSet:
LinkedHashSet is an implementation of the Hash table and LinkedList of the Set interface. This implementation differs from HashSet in that it maintains a bidirectional linked list through all entries. This list defines the order in which elements are inserted into the collection. Note: If elements are re-inserted, the insertion order is not affected.
- The LinkedHashSet has two parameters that affect its composition: the initial capacity and the load factor. They are defined exactly the same as a HashSet. Note, however, that for a LinkedHashSet, choosing a high initial capacity value is less expensive than a HashSet, because the number of iterations of a LinkedHashSet is not affected by capacity.
- Note that the LinkedHashSet is also not thread-safe; if multiple threads access the LinkedHashSet at the same time, it must be locked, or accessed by using
Collections.synchronizedSet
Copy the code
- This class also supports the Fail-fast mechanism
PriorityQueue
AbstractQueue PriorityQueue is an implementation class of AbstractQueue. The elements of a PriorityQueue are sorted either by nature or by providing a Comparator during constructor time, depending on the constructor. PriorityQueue does not allow null elements.
- The head of a queue is, in a sense, the last element in a specified order. The queue lookup operations poll,remove,peek, and Element access the queue head element.
- The priority queue is unlimited, but has an internal capacity that controls the size of the array used to store elements in the queue.
- This class and iterators implement all the optional methods of the Collection and Iterator interfaces. This iterator provides
iterator()
Method does not guarantee traversal of the elements of the priority queue in any particular order. If you need an ordered traversal, consider using itArrays.sort(pq.toArray())
. - Note that this implementation is not thread-safe, multithreads should not concurrently access PriorityQueue instances if a thread modiates the queue, using thread-safe classes
PriorityBlockingQueue
.
HashMap
A HashMap is a collection of elements that use hash table principles and allow empty key-value pairs. HashMap is non-thread-safe, which means that in a multi-threaded environment, there can be problems, whereas Hashtable is thread-safe container. HashMap also supports fail-fast. An instance of a HashMap has two parameters that affect its performance: the initial capacity and the load factor. You can use the Collections. SynchronizedMap (new HashMap (…). ) to construct a thread-safe HashMap.
TreeMap class
A NavigableMap based implementation of the red black tree. The map is stored naturally sorted by key or custom sorted by Comparator.
-
TreeMap provides log(n) time overhead for the containsKey, GET, PUT, and remove methods.
-
Note that this implementation is not thread-safe. If multiple threads concurrently access TreeMap and at least one thread changes the map, an external lock must be performed. This usually by synchronization in natural packaging collection of an object, or use a SortedMap m = Collections synchronizedSortedMap (new TreeMap (…). ).
-
This implementation holds the fail-fast mechanism.
The LinkedHashMap class
LinkedHashMap is the hash and linked list implementation of the Map interface. This implementation differs from HashMap in that it maintains a bidirectional linked list through all of its entries. This list defines the traversal order, usually the order inserted into the map.
-
It provides a special LinkedHashMap(int,float, Boolean) constructor to create a LinkedHashMap traversed in the order in which it was last accessed.
-
The removeEldestEntry(map.entry) method can be overridden to force the removal of expired mapping policies when a new mapping is added to the Map.
-
This class provides all optional map operations and allows null elements. Performance may be lower than a HashMap due to the additional overhead of maintaining a linked list, except for one: Collection-views traversing a LinkedHashMap need to be proportional to map.size, regardless of its capacity. The iteration of a HashMap looks more expensive because it also requires time proportional to its capacity.
-
The LinkedHashMap has two factors that affect its composition: the initial capacity and the load factor.
-
Note that this implementation is not thread-safe. If multiple threads concurrently access the LinkedHashMap, and at least one thread has modified the map, an external lock must be performed. It usually by synchronization in natural packaging collection of an object to achieve the Map m = Collections synchronizedMap (new LinkedHashMap (…). ).
-
This implementation holds the fail-fast mechanism.
Hashtable class
The Hashtable class implements a Hashtable that maps keys to values. Any non-empty object can be used as a key or value.
- This implementation class supports the Fail-fast mechanism
- Unlike the new collection implementation, Hashtable is thread-safe. If a thread-safe container is not required, HashMap is recommended, and if multiple threads are required with high concurrency
ConcurrentHashMap
.
IdentityHashMap class
IdentityHashMap is one of the more niche Map implementations.
- This class is not a generic Map implementation! Although this class implements the Map interface, it deliberately violates the Map convention, which requires the equals method to be used when comparing objects, which is only applicable in rare cases where equality semantics need to be referenced.
- Like HashMap, IdentityHashMap is unordered, and the class is not thread-safe and can be called if you want to make it thread-safe
Collections.synchronizedMap(new IdentityHashMap(...) )
Method to implement. - The FAIL-Fast mechanism is supported
WeakHashMap class
WeakHashMap class is based on Map base implementation of hash table, with weak keys. Entries in WeakHashMap are also automatically removed when they are no longer in use. More precisely, the existence of a mapping for a given key will not prevent the key from being discarded by the garbage collector.
- Based on map interface, it is a kind of weak key connection. The key in WeakHashMap will be recovered automatically
- Null values and null keys are supported.
- Fast – fail mechanism
- No repetition allowed
- WeakHashMap is often used as a cache
The Collections classes
Collections is a separate branch of the Java framework inheritance tree. Collections is a wrapper class that provides some functionality for the Collections framework, including only static method operations or returning Collections.
Synchronous packaging
The synchronization wrapper adds automatic synchronization (thread-safety) to any collection. Each of the six core Collection interfaces (Collection, Set, List, Map, SortedSet, and SortedMap) has a static factory method.
public static Collection synchronizedCollection(Collection c);
public static Set synchronizedSet(Set s);
public static List synchronizedList(List list);
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m);
public static SortedSet synchronizedSortedSet(SortedSet s);
public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m);
Copy the code
Unmodifiable packaging
Immutable wrapper by intercepting modify the collection of operation and throw UnsupportedOperationException, mainly used in the following two scenarios:
- Build the collection and make it immutable. In this case, it is best not to fetch a reference that returns a collection, to ensure immutability
- Allow some clients read-only access to your data structure. You keep references to the returned collection, but distribute references to the wrapper. In this way, customers can view but not modify, while maintaining full access.
These methods are:
public static Collection unmodifiableCollection(Collection<? extends T> c);
public static Set unmodifiableSet(Set<? extends T> s);
public static List unmodifiableList(List<? extends T> list);
public static <K,V> Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> m);
public static SortedSet unmodifiableSortedSet(SortedSet<? extends T> s);
public static <K,V> SortedMap<K, V> unmodifiableSortedMap(SortedMap<K, ? extends V> m);
Copy the code
Thread-safe Collections
Java1.5 and packaging (java.util.concurrent) provides thread-safe Collections that allow for modifications while traversing, By designing the iterator for the fail – fast and throw ConcurrentModificationException. Some implementation classes are CopyOnWriteArrayList, ConcurrentHashMap, CopyOnWriteArraySet
The Collections algorithm
This class contains methods for collection framework algorithms, such as binary search, sort, reorder, reverse, and so on.
Collection implements class feature diagrams
The following figure summarizes the characteristics of some of the main implementation classes of the collection framework, so that you can clearly see the differences between each implementation class
There is also a type of strong citation, weak citation, virtual citation articles, please refer to
Mp.weixin.qq.com/s/ZflBpn2TB…
A generic form
In Jdk1.5, a new concept was introduced, that is, generics, so what are generics?
A generic is simply a parameterized collection that limits the types you can add to the collection. By its very nature, generics are parameterized types. Polymorphism can also be seen as a mechanism for generics. If a class inherits from a parent class, it can find its subclass through its parent class, but it cannot find the specific class through other classes. Generics are designed to be as expressive as possible for objects or methods.
Let’s look at an example of how not generics can be used
List arrayList = new ArrayList();
arrayList.add("cxuan");
arrayList.add(100);
for(int i = 0; i< arrayList.size(); i++){ String item = (String)arrayList.get(i); System.out.println("test === ", item);
}
Copy the code
This program does not work because an Integer cannot be cast directly to a String
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Copy the code
If we were to rewrite it with generics, the sample code would look like this
List<String> arrayList = new ArrayList<String>();
arrayList.add(100);
Copy the code
This code will report errors at compile time, and the compiler will be able to find problems like this at compile time.
The use of generics
Generics can be used in several ways, and let’s explore them together.
Represent classes with generics
Generics can be added to a class to represent the type of that class
// Here T can be written as any identifier. Common parameters such as T, E, K, V are used to represent generics
public class GenericDemo<T>{
//value This member variable is of type T, which is externally specified
private T value;
public GenericDemo(T value) {
this.value = value;
}
public T getValue(a){ // The generic method getKey returns a value of type T, the type of which is externally specified
return value;
}
public void setValue(T value){
this.value = value
}
}
Copy the code
Represent interfaces with generics
Generic interfaces are defined and used in much the same way as generic classes.
// Define a generic interface
public interface Generator<T> {
public T next(a);
}
Copy the code
Generic interfaces are often used in generators, which are equivalent to object factories, a class that is specifically used to create objects.
Generic method
You can use generics to represent methods
public class GenericMethods {
public <T> void f(T x){ System.out.println(x.getClass().getName()); }}Copy the code
Generic wildcard
Lists are generic classes. To represent the parent classes of various generic lists, you can use type wildcards, which use question marks (?). Represents that its element type can match any type. For example,
public static void main(String[] args) {
List<String> name = new ArrayList<String>();
List<Integer> age = new ArrayList<Integer>();
List<Number> number = new ArrayList<Number>();
name.add("cxuan");
age.add(18);
number.add(314);
generic(name);
generic(age);
generic(number);
}
public static void generic(List
data) {
System.out.println("Test cxuan :" + data.get(0));
}
Copy the code
Lower bound wildcard:
This wildcard is all subtypes of the ClassType. It means that any type is a subclass of the ClassType type.
Upper bound wildcard:
This wildcard is all the supertypes of the ClassType. It means that the parent class of any type is ClassType.
reflection
Reflection is a very important and advanced feature in Java, and basically Spring and other frameworks are written with reflection in mind. Let’s first look at what the reflex is.
Java reflection mechanism is in the process of running a program, for any class, can know all its properties and methods; For any object, any attribute and method can be known to call it. The function of dynamically obtaining information and dynamically calling object methods is called reflection mechanism of Java language. (From Baidu.com)
The Java reflection mechanism provides the following functions
- Determine the class to which any object belongs at run time
- Constructs an object of any class at run time
- Determine all member variables and methods of any class at run time
- Call a method of any object at run time
In this way, reflection is like a global player. No matter how your program is running, I know what properties and methods your class has, and who is calling your object.
In Java, the reflection mechanism is implemented using the java.lang.Reflect package. The classes java.lang.Reflect designs are as follows
Here is a simple reflection class
public class Person {
public String name;/ / name
public int age;/ / age
public Person(a) {
super(a); }public Person(String name, int age) {
super(a);this.name = name;
this.age = age;
}
public String showInfo(a) {
return "name=" + name + ", age="+ age; }}public class Student extends Person implements Study {
public String className;/ / class
private String address;/ / address
public Student(a) {
super(a); }public Student(String name, int age, String className, String address) {
super(name, age);
this.className = className;
this.address = address;
}
public Student(String className) {
this.className = className;
}
public String toString(a) {
return "Name:" + name + ", age: + age + Class: + className + Address:"
+ address;
}
public String getAddress(a) {
return address;
}
public void setAddress(String address) {
this.address = address; }}public class TestRelect {
public static void main(String[] args) {
Class student = null;
try {
student = Class.forName("com.cxuan.reflection.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// Get all the public attributes of the object.
Field[] fields = student.getFields();
for (Field f : fields) {
System.out.println(f);
}
System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -");
// Get all attributes of the object except inherited ones.
Field[] declaredFields = student.getDeclaredFields();
for (Field df : declaredFields) {
System.out.println(df);
}
// Get all the public methods of the object
Method[] methods = student.getMethods();
for (Method m : methods) {
System.out.println(m);
}
System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -");
// Get all methods of the object, but not inherited ones
Method[] declaredMethods = student.getDeclaredMethods();
for (Method dm : declaredMethods) {
System.out.println(dm);
}
// Get all the public constructors of the object
Constructor[] constructors = student.getConstructors();
for (Constructor c : constructors) {
System.out.println(c);
}
System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -");
// Get all the constructors of the object
Constructor[] declaredConstructors = student.getDeclaredConstructors();
for (Constructor dc : declaredConstructors) {
System.out.println(dc);
}
Class c = Class.forName("com.cxuan.reflection.Student");
Student stu1 = (Student) c.newInstance();
// The first method instantiates the default constructor and calls set assignment
stu1.setAddress("Shijiazhuang, Hebei");
System.out.println(stu1);
// The second method gets all constructors using constructor assignments
Constructor<Student> constructor = c.getConstructor(String.class,
int.class, String.class, String.class);
Student student2 = (Student) constructor.newInstance("cxuan".24."Six"."Shijiazhuang");
System.out.println(student2);
/** * get method and execute method */
Method show = c.getMethod("showInfo");// Get showInfo()
Object object = show.invoke(stu2);// Call showInfo()}}Copy the code
Some of them are more commonly used, some of them I haven’t seen yet, and here’s a category.
The main classes related to Java reflection are
Class Class
In Java, you generate a class object for every Java Class entity you define. That is, when we write a class and compile it, the generated.class file produces a class object that represents the type information of the class. There is no common constructor in a Class, which means that Class objects cannot be instantiated. Let’s take a quick look at what methods the Class Class includes
toString()
public String toString(a) {
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
}
Copy the code
The toString() method converts an object to a string. ToString () determines whether a Class type is an interface type. That is, ordinary classes and interfaces can be represented by Class objects. There’s also void.
All types are as follows
- Java.lang. Boolean: A wrapper class that represents a Boolean data type
- Java.lang.Character: Wrapper class that represents the char data type
- Java.lang. Byte: Wrapper class that represents the Byte data type
- Java.lang. Short: Wrapper class that represents the Short data type
- Java.lang. Integer: Wrapper class representing the int data type
- Java.lang. Long: Wrapper class that represents the Long data type
- Java.lang. Float: A wrapper class that represents the Float data type
- Java.lang.Double: Wrapper class that represents the Double data type
- Java.lang.Void: Wrapper class that represents the Void data type
Then there is the getName() method, which returns the fully qualified name of the class.
- If it is a reference type, such as string.class.getName () ->
java.lang.String
- For basic data types, byte.class.getName() ->
byte
- New Object[3]).getClass().getName() ->
[Ljava.lang.Object
toGenericString()
This method returns the fully qualified name of the class and includes the class’s modifiers and type parameter information.
forName()
Gets a reference to a Class object based on the Class name. This method initializes the Class object.
For example, Class t = class.forname (” java.lang.thread “) initializes a Thread object
There are three ways to get an instance of a class in Java
- Class.forName(java.lang.Thread)
- Thread.class
- thread.getClass()
newInstance()
Creates an instance of a class that represents objects of that class. The forName() method above initializes the class and the newInstance method instantiates the class.
getClassLoader()
Gets the classloader object.
getTypeParameters()
Gets the object’s parameter type information in the declared order.
getPackage()
Returns the package of the class
getInterfaces()
Get the current Class implementation of the Class or interface, may be multiple, so return the Class array.
Cast
Converts an object to an object that represents a class or interface
asSubclass(Class clazz)
Converts the object of the passed class to an object representing its subclasses
getClasses()
Returns an array containing objects for all public and interface classes in that class
getDeclaredClasses()
Returns an array containing objects for all classes and interface classes in that class
getSimpleName()
Gets the name of the class
getFields()
Get all public property objects
getField(String name)
Gets a public property object
getDeclaredField(String name)
Get a property object
getDeclaredFields()
Get all property objects
getAnnotation(Class annotationClass)
Returns the public annotation object in this class that matches the parameter type
getAnnotations()
Returns all public annotation objects for the class
getDeclaredAnnotation(Class annotationClass)
Returns all annotation objects in the class that match the parameter type
getDeclaredAnnotations()
Returns all the annotation objects for the class
getConstructor(Class… <? > parameterTypes)
Gets the public constructor of the class that matches the parameter type
getConstructors()
Gets all public constructors for the class
getDeclaredConstructor(Class… <? > parameterTypes)
Gets the constructor of the class that matches the parameter type
getDeclaredConstructors()
Gets all constructors for the class
getMethod(String name, Class… <? > parameterTypes)
Gets a public method of that class
getMethods()
Gets all public methods of the class
getDeclaredMethod(String name, Class… <? > parameterTypes)
Gets a method of that class
getDeclaredMethods()
Get all methods of the class
The Field class
The Field class provides information about individual fields in a class or interface, as well as dynamic access to individual fields.
The specific method is not introduced here, readers interested can refer to the official API
Here are just a few common ones
equals(Object obj)
Property equal to obj returns true
get(Object obj)
Get the corresponding attribute value in obj
set(Object obj, Object value)
Set the corresponding property value in obj
Method the class
invoke(Object obj, Object… args)
Pass an object and its parameters to call the corresponding method of the object
This class
Another very important class in reflection is the ClassLoader class, which is used to load classes into the JVM. Classloaders use the parent delegate model to search for loaded classes, which is also known as the parent delegate model. The class inheritance diagram for ClassLoader is shown below
The enumeration
Enumerations are probably the feature we use less often. In Java, enumerations are represented by the enum keyword. Enumerations are actually a very useful feature, and you can think of them as classes with specific properties. Enum is not only in Java, but also in C and C++. Here is an example of an enumeration.
public enum Family {
FATHER,
MOTHER,
SON,
Daughter;
}
Copy the code
Above we created a Family enumeration class with four values, all in uppercase letters because the enumeration types are constants. So how do you refer to enum?
public class EnumUse {
public static void main(String[] args) { Family s = Family.FATHER; }}Copy the code
Enumeration features
When you create an enum, the compiler automatically adds the toString() method to your enum. It allows you to display the name of the enum instance. In addition to the toString() method, the compiler adds the ordinal() method, which represents the order in which enum constants are declared, and the values() method displays the order of values.
public static void main(String[] args) {
for(Family family : Family.values()){
System.out.println(family + ", ordinal"+ family.ordinal()); }}Copy the code
Enum The package can be statically imported without entering the enumeration class name. Constants, you can just use constants, isn’t that amazing? You can statically import packages using the ennum and static keywords
The above code imports all constants in Family, or you can specify constants separately.
Enumerations are the same as normal classes
Enumerations are just like ordinary classes. Except for the convenience of defining constants in enumerations, we can use enumerations to define public static final XXX. You can define properties and methods in enumerations, too. Don’t think of it as an outlier, it’s one of a million classes.
public enum OrdinalEnum {
WEST("live in west"),
EAST("live in east"),
SOUTH("live in south"),
NORTH("live in north");
String description;
OrdinalEnum(String description){
this.description = description;
}
public String getDescription(a) {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public static void main(String[] args) {
for(OrdinalEnum ordinalEnum : OrdinalEnum.values()){ System.out.println(ordinalEnum.getDescription()); }}}Copy the code
Generally, switch can be used with enum to construct a small state transition machine.
enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change(a) {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break; }}}Copy the code
Does the code suddenly feel a little cleaner and more elegant?
Enumerate the mysteries
In Java, everything is an object. Enum is a keyword, but it implicitly inherits from the enum class. Let’s take a look at the Enum class, which is in the java.lang package and can be referenced automatically.
This class has fewer properties and methods. You’ll notice that our values method is missing from this class. As mentioned earlier, values() is the static method that the compiler adds when you use enumerations. You can verify this using reflection.
In addition, enum has an intersection with the Class Class, where there are three methods on enum
The first two methods are used to get enum constants, and isEnum is used to determine if an enum is used.
Enumeration class
In addition to enums, there are two utility classes you need to know about enumerations: EnumSet and EnumMap
Enumsets and EnumMap
Introduced in JDK1.5, EnumSet is designed with speed in mind and can be used as an efficient alternative to Enum.
EnumMap is a special Map that requires the key value to come from an enum. Because EnumMap is also fast, we can use EnumMap for quick key lookups.
In general, enumerations aren’t that complicated to use, and they’re a small piece of Java functionality, but sometimes you can make your code elegant and clean with just one little trick.
I/O
Creating a good I/O program is very complex. JDK developers write a lot of classes just to be able to create a good toolkit, and writing an I/O toolkit must be a lot of work.
The IO class is designed to solve IO related operations. The most common I/O read and write operations are networks and disks. In Java, operating on a file is a typical I/O operation. Let’s make a classification of I/O.
Public id reply IO to obtain mind map
I/ OS can also be distinguished by operation objects
In addition, there are other classes that are important in I/O
The File type
The File class is a class that operates on files and folders in the File system. You can manipulate files and folders with object-oriented thinking. Isn’t it amazing?
File creation involves creating, deleting, and obtaining file descriptors
class FileDemo{
public static void main(String[] args) {
File file = new File("D:\\file.txt");
try{
f.createNewFile(); // Create a file
// Two constants of the File class
// Path delimiter (system specific) < Windows is; In Linux: >
System.out.println(File.pathSeparator); / /;
// System-specific path name delimiter < Windows yes/Linux yes / >
System.out.println(File.separator); / / /
// Delete files
/* File file = new File(fileName); if(f.exists()){ f.delete(); }else{system.out.println (" file does not exist "); } * /
}catch(Exception e) { e.printStackTrace(); }}}Copy the code
You can also operate on folders
class FileDemo{
public static void main(String[] args) {
String fileName = "D:"+ File.separator + "filepackage";
File file = new File(fileName);
f.mkdir();
// List all files
/* String[] str = file.list(); for (int i = 0; i < str.length; i++) { System.out.println(str[i]); } * /
/ / using the file. ListFiles (); Lists all files, including hidden files
// Use file.isdirectory () to determine whether the specified path is a directory}}Copy the code
The above are just two simple examples. In fact, there are some other operations on files that are not used. Creating a file, for example, can be done in one of three ways
File(String directoryPath);
File(String directoryPath, String filename);
File(File dirObj, String filename);
Copy the code
DirectoryPath is the path name of the File, filename is the File name, and dirObj is a File object. For example,
File file = new File("D:\\java\\file1.txt"); // double \\ is an escape
System.out.println(file);
File file2 = new File("D:\\java"."file2.txt");// Parent path, child path - can be applied to multiple files!
System.out.println(file2);
File parent = new File("D:\\java");
File file3 = new File(parent,"file3.txt");//File Class parent path, child path
System.out.println(file3);
Copy the code
Now summarize the File class
Basic IO classes and related methods
There are many. IO classes, but the most basic are four abstract classes: InputStream, OutputStream, Reader, and Writer. The most basic methods are the read() and write() methods, from which all other streams are subclasses and from which methods are derived. And most of the IO source code is native logo, that is, the source code is written in C/C++. Let’s take a look at these stream classes and their methods
InputStream
InputStream is an abstract class that defines Java stream byte input patterns. All methods of this class raise an IOException exception in the event of an error condition. Its main methods are defined as follows
OutputStream
OutputStream is an abstract class that defines the stream byte output pattern. All methods of this class return a void value and raise an IOException in case of an error. Its main methods are defined as follows
Reader class
Reader is an abstract class for the Java-defined streaming character input pattern. Methods in a class raise IOException when an error occurs.
Writer class
Writer is an abstract class that defines streaming character output. All methods of this class return a void value and raise IOException in case of an error
InputStream and its subclasses
FileInputStream: The FileInputStream class creates an InputStream class that reads bytes from a file
ByteArrayInputStream ByteArrayInputStream: a buffer in memory is used as an InputStream
PipedInputStream Pipe input stream: Implements the concept of a PIPE pipe and is primarily used in threads
SequenceInputStream Sequential input streams: Combine multiple InputStreams into one InputStream
FilterOutputStream Filter input stream: wrapper for other input streams.
ObjectInputStream Deserializes input stream: Restores the original data previously serialized with ObjectOutputStream to an object and reads the object as a stream
DataInputStream: a DataInputStream allows an application to read basic Java data types from the underlying input stream in a machine-independent manner.
PushbackInputStream: A novel use of buffering is to implement pushback. Pushback is used to input the stream to allow bytes to be read and then returned to the stream.
OutputStream and its subclasses
FileOutputStream: This class implements an output stream whose data is written to a file.
ByteArrayOutputStream: This class implements an output stream whose data is written to a buffer of byte arrays that grows automatically as data is written.
PipedOutputStream: The output stream of a pipe, which is the sender of the pipe.
ObjectOutputStream Primitive type output stream: this class serializes an object that has been serialized and writes to the specified location.
FilterOutputStream FilterOutputStream: wrapper for other output streams.
PrintStream Allows you to print text to a file or network.
DataOutputStream: a DataOutputStream allows an application to write basic Java data types to the underlying output stream in a machine-independent manner.
Reader and its subclasses
FileReader file character input stream: Converts a file to a character stream read in
CharArrayReader: is an implementation of an input stream that takes an array of characters as its source
BufferedReader Buffer input stream: The BufferedReader class reads text from the character input stream and buffers characters to efficiently read characters, arrays, and lines
PushbackReader: The PushbackReader class allows one or more characters to be sent back to the input stream.
PipedReader input stream: The main purpose of PipedReader is also to communicate between threads, but this can be used to transfer characters
Writer and its subclasses
FileWriter: FileWriter creates a Writer class that can write to files.
CharArrayWriter Character array output stream: CharArrayWriter implements an output stream that targets arrays.
BufferedWriter Buffer output stream: BufferedWriter is a Writer with the flush() method added. The flush() method can be used to ensure that the data buffer is actually written to the actual output stream.
PrintWriter: A PrintWriter is essentially a character version of PrintStream.
PipedWriter pipe output stream: The main purpose of PipedWriter is also to communicate between threads, but this can be used to transfer characters
Java’s streaming interface for input and output provides a neat abstraction for complex and onerous tasks. The combination of filter stream classes allows you to dynamically create client-side streaming interfaces to match data transfer requirements. Java programs that inherit from the advanced InputStream, InputStreamReader, Reader, and Writer classes can be used reasonably in the future, even when new and improved concrete classes are created.
annotations
Java annotations, also known as metadata, provide a formal way to add information to your code. Introduced in JDK1.5, Java defines a set of seven annotations, three in java.lang and four in java.lang.annotation.
There are three annotations that apply to the code
@Override
: override flag, used when a subclass inherits its parent class and marks the method of the overridden subclass. If the method is not found in the parent class or in the referenced interface, a compilation error is reported.@Deprecated
: The code annotated with this annotation is outdated and no longer recommended@SuppressWarnings
This annotation ignores the compiler’s warning
There are four meta-annotations, which are the annotations used to mark the annotations. They are
@Retention
: Identifies how it is stored, whether it is stored only in code, marshaled in a class file, or accessible by reflection at run time.
Retentionpolicy. SOURCE: Annotations are retained only in the SOURCE file. When Java files are compiled into class files, annotations are discarded.
Retentionpolicy. CLASS: Annotations are kept in the CLASS file, but are discarded when the JVM loads the CLASS file, which is the default lifecycle;
Retentionpolicy. RUNTIME: Annotations are not only saved to the class file, but still exist after the JVM loads the class file.
@Documented
: marks whether these annotations are included in JavaDoc.@Target
: Mark this Annotation describes the range of objects that the Annotation is modifying, Annotations can be used for packages, types (classes, interfaces, enumerations, Annotation types), type members (methods, constructors, member variables, enumerated values), method parameters, and local variables (such as loop variables, catch parameters). The following values
public enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE
Copy the code
@Inherited
: marks the annotation class from which the annotation is inherited.
Since JDK1.7, three additional annotations have been added, which are
-
SafeVarargs: The Java compiler will emit an unchecked warning when declaring variadic constructors or methods. You can ignore these warnings with @safevarargs
-
@functionalinterface: indicates that this method is a FunctionalInterface
-
Repeatable: Indicates that an annotation can be used multiple times on the same statement.
Note: Annotations do not support inheritance.
Several ways to handle null
Null Pointers have always been an annoying problem for Java programmers, and nullPointerExceptions often plague our development efforts. Java’s inventors also acknowledged that this was a huge design mistake.
Here are a few things you should know about NULL to effectively understand it and avoid many null-induced errors.
Case sensitivity
First, NULL is a Java keyword, such as **public, static, and final. ** It is case sensitive, you cannot write NULL as NULL or null, the editor will not recognize them and report an error.
This problem is almost nonexistent because the Eclipse and Idea compilers already give compiler hints, so you don’t have to worry about it.
Null is the initial value for any reference type
Null is the default value for all reference types. Any reference variable in Java uses NULL as the default value. That is, all reference types under Object are null by default. This is true for all reference variables. Just like the default values for primitive types, for example, int defaults to 0 and Boolean defaults to false.
Here are the initial values for the basic data types
Null is just a special kind of value
Null is neither an object nor a type. It is just a special value that you can assign to any type. You can convert NULL to any type
public static void main(String[] args) {
String str = null;
Integer itr = null;
Double dou = null;
Integer integer = (Integer) null;
String string = (String)null;
System.out.println("integer = " + integer);
System.out.println("string = " + string);
}
Copy the code
As you can see, it is possible to convert NULL to any reference type at compile time and run time without throwing a null-pointer exception.
Null can only be assigned to reference variables, not primitives.
A wrapper class that holds NULL cannot be converted when unboxing itself, throws a null pointer exception, and null cannot be compared to a primitive data type
public static void main(String[] args) {
int i = 0;
Integer itr = null;
System.out.println(itr == i);
}
Copy the code
A reference type variable with a null value is used,instanceof
The action returns false
public static void main(String[] args) {
Integer isNull = null;
// instanceof = isInstance
if(isNull instanceof Integer){
System.out.println("isNull is instanceof Integer");
}else{
System.out.println("isNull is not instanceof Integer"); }}Copy the code
This is an important feature of the Instanceof operator, which makes casting checks useful
Calling a static method with a static variable null does not throw a NullPointerException. Because static methods use static binding.
Use the null-safe method
You should use null-safe methods. There are many utility classes in the Java class library that provide static methods, such as wrapper classes for primitive data types, Integer, Double, and so on. For example,
public class NullSafeMethod {
private static String number;
public static void main(String[] args) {
String s = String.valueOf(number);
String string = number.toString();
System.out.println("s = " + s);
System.out.println("string = "+ string); }}Copy the code
The String. Value (number) static method does not raise a null-pointer exception, but toString() does. So use static methods of objects whenever possible.
Null judgments
You can use == or! The = operation compares null values, but no other algorithm or logical operation, such as less than or greater than, can be used. Unlike SQL, null == null in Java returns true, as shown below:
public class CompareNull {
private static String str1;
private static String str2;
public static void main(String[] args) {
System.out.println("str1 == str2 ? " + str1 == str2);
System.out.println(null= =null); }}Copy the code
About mind mapping
I’ve put together some mind maps for common Java toolkits for your convenience.
Java.IO
Java.lang
Java.math
Java.net