Welcome to the original text: www.yuque.com/dobbykim/java-basic/...
1: Overview of cross platform and bytecode of Java language
JVM, machine code and bytecode
JVM: Java Virtual Machine is also called Java Virtual Machine.
Java language has one feature: platform independence. JVM is the key to realize this feature.
We know that software operation depends on the Operating System. The programming language used by early developers did not have good portability. If you want to run applications with the same function on different Operating System platforms, you need to write code that can be recognized by the platform for each platform. Generally, the compiler will directly compile the source code of the program into machine code that the computer can execute directly.
The Java language is platform independent, which is called Write Once,Run Anywhere. The java compiler does not compile the Java source code into the machine code that can be directly executed by the computer composed of 0 and 1 sequences, but compiles it into the machine code with the extension Bytecode of class. If you want to execute bytecode files, the JVM must be installed on the platform, and the JVM interpreter will interpret the bytecode as a platform dependent machine code.
It can also be seen from the above figure that different operating systems need to install JVMs based on the operating system. JVM shields the differences between operating systems and realizes the cross platform of Java language.
2: The basic unit of Java language -- classes and packages
class
In the Java language, classes are the smallest basic unit
One of the simplest classes
public class Cat { }
package
In order to better organize classes, the Java language provides a package mechanism to distinguish the namespace of class names.
Example:
One belongs to my Cat class under cut package
package my.cute; public class Cat { }
In the Java language, packages are generally named in the reverse order of domain names.
For example:
package com.alibaba.fastjson;
This avoids class name conflicts.
3: The basic structure of Java language -- the meaning of package
Meaning and function of package:
Organize similar or related classes in the same package to facilitate search and management
Class names in the same package cannot be the same, but class names in different packages can be the same; When calling a class with the same class name in two different packages at the same time, the package name should be added to distinguish it. Therefore, the package can also avoid class name conflicts. Example: for classes with the same class name under different packages, we can use the fully qualified name to distinguish them.
package com.github.hcsp; public class Home { com.github.hcsp.pet1.Cat cat1; com.github.hcsp.pet2.Cat cat2; }
The package limits access
4: Introducing third-party packages into Java
Example: introduce a class in a third-party package into the program: org apache. commons. langs. StringUtils.
If Maven is used for project management, we first need to introduce it into the pom file Apache Commons Lang Package dependency
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.11</version> </dependency>
Then go back to our code and use the import keyword to introduce third-party packages
As follows:
package com.github.hcsp; import org.apache.commons.lang3.StringUtils; public class Main { public static void main(String[] args) { System.out.println("Empty string is empty: " + StringUtils.isEmpty("")); } }
Program input results:
Empty string is empty: true
We found that the above procedures, whether String or System, are not fully qualified by import ing and writing the class name, but are used directly.
That's because the String and System classes are placed in Java Under the package.
The Java language stipulates that if a class is placed in Java Lang package, we can use it directly instead of writing import and fully qualified class name.
5: Methods, static methods and static member variables
main method
The entry of Java program execution is the main method
Program example:
package com.github.hcsp; public class Main { public static void main(String[] args) { } }
main method signature:
Public modifier: public represents the public class. There is no restriction and it can be called freely
Static modifier: static stands for static. Methods and variables decorated with static are not bound to any object, which means that we can call without creating any object
void: indicates that the method has no return value
String[] args: command line parameter passed to main method, expressed as string array
Static methods and static member variables
Program example 1:
package com.github.hcsp; public class Main { public static void main(String[] args) { int i = 0; add(i); add(i); add(i); System.out.println(i); } public static void add(int i){ i++; } }
The program output result is:
0
The reason is that the parameter i passed in the add method only acts in the add method block, so it cannot have any impact on the variable i in the main method.
Program example 2:
package com.github.hcsp; public class Main { public static int i = 0; public static void main(String[] args) { add(); add(); add(); } public static void add() { i++; } }
The result of this program is:
3
The method or member variable modified by static is independent of any object of the class, or does not depend on any object. It is a piece of memory in the JVM and a global storage unit that can be shared by all objects. So the add method will affect it.
6: Objects, constructors, and member variables
Java is an object-oriented language.
Class is an abstract concept, while object is an instance of class and a concrete concept.
Example: create an object
Cat
package com.github.hcsp; public class Cat { private String name; public Cat(){ } public Cat(String name) { this.name = name; } }
Main
package com.github.hcsp; public class Main { public static void main(String[] args) { Cat cat = new Cat("Tom"); } }
The easiest way to create an object is to use the new keyword
In this example, we create a Cat object named Tom and call the constructor with parameters.
If we do not declare any constructor in the Cat class, the compiler will automatically declare a parameterless constructor for us; On the contrary, if we declare any constructor with parameters, the compiler will not automatically declare the constructor without parameters for us, and we need to declare it ourselves.
7: Instance method and null pointer exception
Sample program:
Cat
package com.github.hcsp; public class Cat { private String name; public Cat() { } public Cat(String name) { this.name = name; } public void meow() { System.out.println("Meow, I am " + name); } }
Main
package com.github.hcsp; public class Main { public static void main(String[] args) { Cat cat1 = new Cat("Tom"); Cat cat2 = new Cat("Harry"); cat1.meow(); cat2.meow(); } }
Program output results:
Meow, I am Tom Meow, I am Harry
Let's look at this program:
Cat
package com.github.hcsp; public class Cat { private String name; public Cat() { } public Cat(String name) { this.name = name; } public void meow() { System.out.println("Meow, I am " + name + ", The length of my name is:" + name.length()); } }
package com.github.hcsp; public class Main { public static void main(String[] args) { Cat cat1 = new Cat(); Cat cat2 = new Cat("Tom"); cat1.meow(); cat2.meow(); } }
Running program:
Exception in thread "main" java.lang.NullPointerException at com.github.hcspTest.Cat.meow(Cat.java:15) at com.github.hcspTest.Main.main(Main.java:8)
We will find that there is an exception when the program runs. This exception is NullPointerException, that is, null pointer exception
The reason is that the name of cat1 is null. For an empty object, when we call the method of this object, a null pointer exception will be generated.
The method to avoid null pointers is very simple. We can add the logic processing of null judgment where null pointers may be generated:
public void meow(){ if(name == null){ System.out.println("I don't have a name yet!"); }else { System.out.println("Meow, I am " + name + ", The length of my name is:" + name.length()); } }
8: Object and reference details
Reference
for instance:
A a = new A();
A is a reference, which points to an a object. We manipulate the reference a indirectly by manipulating the object it points to.
Sample program:
Cat
package com.github.hcsp; public class Cat { public String name; public Cat() { } public Cat(String name) { this.name = name; } public void meow() { System.out.println("Meow, I am " + name + ", The length of my name is:" + name.length()); } }
Home
package com.github.hcsp; public class Home { Cat cat; public static void main(String[] args) { Home home = new Home(); Cat mimi = new Cat(); home.cat = mimi; mimi.name = "mimi"; } }
The memory diagram of the program is analyzed as follows:
Deep copy and shallow copy
The fundamental difference between shallow copy and deep copy is whether the copied object is a copy entity of an object, not a reference.
Take an example to describe:
Suppose B is a copy of A
When we modify A, if B also changes, it is A shallow copy, indicating that we modify the same value in the heap memory;
When we modify A, if B does not change, it is A deep copy, indicating that we modify different values in heap memory
Implement the clonable interface, rewrite the clone() method and call it. What we get is a shallow copy of an object, such as the example program:
Cat
package com.github.hcsp; public class Cat implements Cloneable { public String name; public Cat() { } public Cat(String name) { this.name = name; } @Override protected Object clone() { Cat cat = null; try { cat = (Cat) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return cat; } }
Main
package com.github.hcsp; public class Main { public static void main(String[] args) { Cat cat = new Cat(); Cat newCat = (Cat) cat.clone(); // clone method is a shallow copy } }
So how to implement deep copy?
Deep copy sample program:
Cat
package com.github.hcsp; public class Cat { public String name; public Cat() { } public Cat(String name) { this.name = name; } }
Home
package com.github.hcsp; public class Home { Cat cat; }
DeepCopy
public class DeepCopy { public static void main(String[] args) { Home home = new Home(); Cat cat = new Cat(); cat.name = "mimi"; home.cat = cat; Home newHome = deepCopy(home); } public static Home deepCopy(Home home) { Home newHome = new Home(); Cat newCat = new Cat(); String newName = new String(home.cat.name); newHome.cat = newCat; newCat.name = newName; return newHome; } }
This enables a deep copy
9: Value passing vs reference passing of method
Let's look at two procedures first
Procedure I:
package com.github.hcsp; public class Main { public static void main(String[] args) { int i = 0; addOne(i); System.out.println(i); } static void addOne(int i) { i++; } }
The output of the program is:
0
Because the i passed in the addOne method is only a copy of the value of i in the main method, it will not have any impact on it. After the addOne method is executed, the method space will be destroyed.
Procedure 2:
package com.github.hcsp; public class Main { public static void main(String[] args) { Cat cat = new Cat(); cat.name = "haha"; renameCat(cat); System.out.println(cat.name); } static void renameCat(Cat cat){ cat.name = "mimi"; } }
The result of this program is:
mimi
Why does the program change the name of cat? Because the method passes a copy of the cat variable reference (address), the cat in the rename method points to the same "cat" in memory.
What is value passing? pass by value refers to transferring a copy of the actual parameters to the function when calling the function, so that if the parameters are modified in the function, the actual parameters will not be affected.
What is reference passing? pass by reference refers to directly passing the address of the actual parameter to the function when calling the function. Then the modification of the parameter in the function will affect the actual parameter.
There are two data types in Java:
Primitive Data Type
int
char
byte
boolean
float
double
short
long
Reference data type
In Java, the parameter passing of a method, whether it is a native data type or a reference data type, is essentially the same.
If it is value transfer, copy the value; if it is reference (address), copy the reference (address).
Therefore, for basic types, Java will directly copy a value and pass it to the method. Therefore, the method only modifies the copied value and does not affect the original value; For a reference type, Java will copy the address of the reference and pass it as a value to the method. What is passed in the method is the address in the heap memory, which is equivalent to operating on the same object in the heap memory, so the information of the object will be changed.