14
头图

This "Java Basic Knowledge Summary" is the read article on 160857cf202bbb JavaGuide . Since I have refactored it and fixed many small problems, I will synchronize it on segmentfault!

The content of the article is more, the directory is as follows:

Basic concepts and common sense

What are the characteristics of the Java language?

  1. Easy to learn;
  2. Object-oriented (encapsulation, inheritance, polymorphism);
  3. Platform independence (Java virtual machine realizes platform independence);
  4. Support multi-threading (C++ language does not have a built-in multi-threading mechanism, so the multi-threading function of the operating system must be called for multi-threading programming, while Java language provides multi-threading support);
  5. reliability;
  6. safety;
  7. Supports network programming and is very convenient (the birth of the Java language itself is designed to simplify network programming, so the Java language not only supports network programming but also is very convenient);
  8. Compilation and interpretation coexist;
Amendment (see: issue#544 ): C++11 started (in 2011), C++ introduced a multi-threaded library, in windows, linux, macos, you can use std::thread and std::async to create threads. Reference link: http://www.cplusplus.com/reference/thread/thread/?kw=thread

JVM vs JDK vs JRE

JVM

The Java Virtual Machine (JVM) is a virtual machine that runs Java bytecode. JVM has specific implementations for different systems (Windows, Linux, macOS), the purpose is to use the same bytecode, they will all give the same result.

What is bytecode? What are the benefits of using bytecode?

In Java, the code that the JVM can understand is called bytecode (that is .class ), which does not face any specific processor, but only faces the virtual machine. The Java language uses bytecode to solve the problem of low execution efficiency of traditional interpreted languages to a certain extent, while retaining the portability of interpreted languages. Therefore, Java programs are more efficient when running, and because the bytecode is not specific to a specific machine, Java programs can run on computers with different operating systems without recompilation.

Java programs generally have the following 3 steps from source code to execution:

Java程序运行过程

What we need to pay special attention to is the step of .class->machine code. In this step, the JVM class loader first loads the bytecode file, and then interprets and executes it line by line through the interpreter. The execution speed of this method will be relatively slow. Moreover, some methods and code blocks are often called (the so-called hot code), so the JIT compiler was introduced later, and JIT belongs to runtime compilation. When the JIT compiler completes the first compilation, it saves the machine code corresponding to the bytecode, and can be used directly next time. And we know that the operating efficiency of machine code is definitely higher than that of the Java interpreter. This also explains why we often say that Java is a language where compilation and interpretation coexist.

HotSpot adopts the method of Lazy Evaluation. According to the twenty-eight law, only a small part of the code (hot code) consumes most of the system resources, and this is the part that JIT needs to compile. The JVM collects information based on each execution of the code and makes some optimizations accordingly. Therefore, the more times it is executed, the faster it will be. JDK 9 introduced a new compilation mode AOT (Ahead of Time Compilation), which directly compiles bytecode into machine code, thus avoiding various overheads such as JIT preheating. JDK supports hierarchical compilation and AOT collaborative use. However, the compilation quality of the AOT compiler is definitely not as good as the JIT compiler.

summary:

The Java Virtual Machine (JVM) is a virtual machine that runs Java bytecode. JVM has specific implementations for different systems (Windows, Linux, macOS), the purpose is to use the same bytecode, they will all give the same result. Bytecode and JVM implementation of different systems are the key to Java language "compile once, run anywhere".

JDK and JRE

JDK is the abbreviation of Java Development Kit, it is a full-featured Java SDK. It has everything the JRE has, as well as the compiler (javac) and tools (such as javadoc and jdb). It can create and compile programs.

JRE is the Java runtime environment. It is a collection of everything needed to run a compiled Java program, including the Java Virtual Machine (JVM), Java class libraries, java commands and other basic components. However, it cannot be used to create new programs.

If you just want to run a Java program, then you only need to install JRE. If you need to do some Java programming work, then you need to install the JDK. However, this is not absolute. Sometimes, even if you do not plan to do any Java development on your computer, you still need to install the JDK. For example, if you want to deploy a web application using JSP, then technically speaking, you are just running a Java program in an application server. So why do you need JDK? Because the application server will convert JSP to Java servlet, and need to use JDK to compile the servlet.

Why is the Java language "compilation and interpretation coexisting"?

High-level programming languages are divided into two types: compiled and interpreted according to the way the program is executed. In simple terms, a compiled language means that the compiler translates the source code into machine code that can be executed by the platform at one time for a specific operating system; an interpreted language means that the interpreter interprets the source program line by line into a machine on a specific platform. Code and execute immediately. For example, if you want to read an English masterpiece, you can find an English translator to help you read it.
There are two options. You can wait for the translator to translate the entire English masterpiece (that is, the source code) into Chinese, and then read it, or you can ask the translator to translate a paragraph. You can read a paragraph next to the book and slowly read the book. Finished reading.

The Java language has both the characteristics of a compiled language and an interpreted language, because the Java program has to be compiled first and then interpreted in two steps. The program written by Java needs to go through the compilation step first to generate the bytecode ( \*.class file). ), this kind of bytecode must be interpreted and executed by the Java interpreter. Therefore, we can think of the coexistence of Java language compilation and interpretation.

Comparison of Oracle JDK and OpenJDK

Maybe many people like me have not touched or used OpenJDK before looking at this issue. So is there a major difference between Oracle and OpenJDK? Below I will use some of the information I have collected to answer this question that has been overlooked by many people.

For Java 7, there is nothing critical. The OpenJDK project is mainly based on the HotSpot source code donated by Sun. In addition, OpenJDK was selected as the reference implementation of Java 7 and is maintained by Oracle engineers. Regarding the difference between JVM, JDK, JRE and OpenJDK, an Oracle blog post in 2012 has a more detailed answer:

Q: What is the difference between the source code in the OpenJDK repository and the code used to build the Oracle JDK?

Answer: Very close-our Oracle JDK version build process is based on OpenJDK 7, with only a few parts added, such as deployment code, which includes the implementation of Oracle's Java plug-in and Java WebStart, as well as some closed source code party components, such as Graphics rasterizer, some open source third-party components, such as Rhino, and some odds and ends, such as additional documents or third-party fonts. Looking to the future, our goal is to open source all parts of the Oracle JDK, except for the part where we consider commercial functions.

summary:

  1. Oracle JDK releases a major version approximately every 6 months, while the OpenJDK version releases approximately every three months. But this is not fixed, I think it is useless to understand this. For details, please refer to: https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence .
  2. OpenJDK is a reference model and is completely open source, while Oracle JDK is an implementation of OpenJDK, not completely open source;
  3. Oracle JDK is more stable than OpenJDK. The code of OpenJDK and Oracle JDK are almost the same, but Oracle JDK has more classes and some bug fixes. Therefore, if you want to develop enterprise/commercial software, I suggest you choose Oracle JDK because it has been thoroughly tested and stable. In some cases, some people mentioned that they may encounter many application crashes when using OpenJDK, but just switch to Oracle JDK to solve the problem;
  4. In terms of responsiveness and JVM performance, Oracle JDK provides better performance than OpenJDK;
  5. Oracle JDK will not provide long-term support for the upcoming version, and users must obtain the latest version by updating to the latest version to obtain support each time;
  6. Oracle JDK is licensed under the BCL/OTN agreement, while OpenJDK is licensed under the GPL v2 license.

🌈 Expand it a bit:

  • BCL Agreement (Oracle Binary Code License Agreement): JDK can be used (commercially supported), but it cannot be modified.
  • OTN agreement (Oracle Technology Network License Agreement): 11 and later newly released JDK use this agreement, you can use it privately, but you need to pay for commercial use.

Related reading 👍: "Differences Between Oracle JDK and OpenJDK"

What is the difference between Java and C++?

I know that many people have never studied C++, but the interviewer just likes to compare Java and C++! no way! ! ! Even if you haven't learned C++, write it down!

  • Both are object-oriented languages and support encapsulation, inheritance and polymorphism
  • Java does not provide pointers to directly access memory, and program memory is more secure
  • Java classes are single inheritance, and C++ supports multiple inheritance; although Java classes cannot be multiple inheritance, interfaces can be multiple inheritance.
  • Java has an automatic memory management garbage collection mechanism (GC), which does not require programmers to manually release useless memory.
  • C++ supports both method overloading and operator overloading, but Java only supports method overloading (operator overloading adds complexity, which is inconsistent with the original design idea of Java).
  • ......

What is the difference between import java and javax?

At the beginning, the required package for JavaAPI was the package beginning with java, and javax was only used by extending the API package at that time. However, over time, javax has gradually expanded to become an integral part of the Java API. However, moving the extension from the javax package to the java package is really too cumbersome and will eventually break a bunch of existing code. Therefore, it was finally decided that the javax package would become part of the standard API.

So, there is actually no difference between java and javax. It's all a name.

Basic grammar

What is the difference between character constants and string constants?

  1. form : A character constant is a character enclosed in single quotes, and a string constant is 0 or several characters enclosed in double quotes
  2. Meaning : A character constant is equivalent to an integer value (ASCII value) and can participate in expression operations; a string constant represents an address value (the string is stored in the memory location)
  3. occupies the memory size : character constant only occupies 2 bytes; string constant occupies several bytes ( Note: char occupies two bytes in Java ),

    The character encapsulation class Character has a member constant Character.SIZE value is 16, and the unit is bits . This value is divided by 8 ( 1byte=8bits ) to get 2 bytes
Java Programming Thought Fourth Edition: Section 2.2.2

Annotation

There are three types of comments in Java:

  1. Single line comment
  2. Multi-line comments
  3. Document comments.

When we write code, if the amount of code is relatively small, we or other members of the team can easily understand the code, but once the project structure becomes complicated, we need to use comments. The comments will not be executed (the compiler will erase all the comments in the code before compiling the code, and the comments are not retained in the bytecode), which is written by our programmers for ourselves. The comments are your code specifications, which can help The person watching the code quickly clarifies the logical relationship between the codes. Therefore, it is a very good habit to add comments when writing programs.

The book "Clean Code" clearly states:

code comments are not as detailed as possible. In fact, good code itself is comments, and we should try our best to standardize and beautify our code to reduce unnecessary comments.

If the programming language is expressive enough, there is no need to comment, and try to explain it through code.

for example:

Remove the following complicated comments, just create a function that is the same thing as the comment

// check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))

Should be replaced with

if (employee.isEligibleForFullBenefits())

What is the difference between identifiers and keywords?

When we write programs, we need to give a lot of names to programs, classes, variables, methods, etc., so there is an identifier. In short, an identifier is a name. But there are some identifiers that the Java language has given them special meanings and can only be used in specific places. Such special identifiers are keywords. Therefore, keywords are identifiers that are given special meanings. For example, in our daily life, the name "police station" has been given a special meaning, so if you open a store, the name of the store cannot be called "police station", "police station" is our daily life Keywords.

What are the common keywords in Java?

Access controlprivateprotectedpublic
Class, method and variable modifiersabstractclassextendsfinalimplementsinterfacenative
newstaticstrictfpsynchronizedtransientvolatile
Program controlbreakcontinuereturndowhileifelse
forinstanceofswitchcasedefault
Error handlingtrycatchthrowthrowsfinally
Package relatedimportpackage
basic typebooleanbytechardoublefloatintlong
shortnulltruefalse
Variable referencesuperthisvoid
Reserved wordgotoconst

Increment and Decrement Operator

In the process of writing code, a common situation is that an integer type variable needs to be increased or decreased by 1. Java provides a special operator for this kind of expression, called the increment operator (++ ) And the decrement operator (--).

The ++ and - operators can be placed before or after the variable. When the operator is placed before the variable (prefix), it is incremented/decremented first, and then assigned; when the operator is placed after the variable ( Suffix), first assign the value, and then increase/decrease. For example, when b = ++a , first increment (increase by 1), and then assign (assign to b); when b = a++ , first assign (assign to b), and then increment (increase by 1). That is, ++a outputs the value of a+1, and a++ outputs the value of a. A mantra is: "add/subtract after the sign, add/subtract after the sign."

What is the difference between continue, break, and return?

In the loop structure, when the loop conditions are not met or the number of loops reaches the requirement, the loop will end normally. However, sometimes it may be necessary to terminate the loop prematurely when a certain condition occurs in the process of the loop, which requires the use of the following keywords:

  1. continue: Refers to jumping out of the current loop and continuing to the next loop.
  2. break: refers to jumping out of the entire loop body and continuing to execute the statement below the loop.

return is used to jump out of the method and end the operation of the method. There are generally two uses for return:

  1. return; : directly use return to end method execution, used for methods that do not have a return value function
  2. return value; : return a specific value for methods with return value functions

Do you understand Java generics? What is type erasure? Tell me about the commonly used wildcards?

Java generics (generics) is a new feature introduced in JDK 5. Generics provide a compile-time type safety detection mechanism, which allows programmers to detect illegal types at compile time. The essence of generics is a parameterized type, which means that the type of data being manipulated is specified as a parameter.

Java's generics are pseudo-generics. This is because all generic information will be erased during Java compilation, which is commonly referred to as type erasure.

List<Integer> list = new ArrayList<>();

list.add(12);
//这里直接添加会报错
list.add("a");
Class<? extends List> clazz = list.getClass();
Method add = clazz.getDeclaredMethod("add", Object.class);
//但是通过反射添加,是可以的
add.invoke(list, "kl");

System.out.println(list);

There are generally three ways to use generics: generic classes, generic interfaces, and generic methods.

1. Generic class :

//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{

    private T key;

    public Generic(T key) {
        this.key = key;
    }

    public T getKey(){
        return key;
    }
}

How to instantiate a generic class:

Generic<Integer> genericInteger = new Generic<Integer>(123456);

2. Generic interface :

public interface Generator<T> {
    public T method();
}

Implement a generic interface without specifying the type:

class GeneratorImpl<T> implements Generator<T>{
    @Override
    public T method() {
        return null;
    }
}

Implement a generic interface, specify the type:

class GeneratorImpl<T> implements Generator<String>{
    @Override
    public String method() {
        return "hello";
    }
}

3. Generic method :

   public static < E > void printArray( E[] inputArray )
   {
         for ( E element : inputArray ){
            System.out.printf( "%s ", element );
         }
         System.out.println();
    }

use:

// 创建不同类型数组: Integer, Double 和 Character
Integer[] intArray = { 1, 2, 3 };
String[] stringArray = { "Hello", "World" };
printArray( intArray  );
printArray( stringArray  );

used wildcards for 160857cf2057dd are: T, E, K, V,?

  • ? Represents an uncertain java type
  • T (type) represents a specific java type
  • KV (key value) respectively represents the Key Value in the java key value
  • E (element) stands for Element

The difference between == and equals

For basic data types, == compares values. For reference data types, == compares the memory address of the object.

Because Java only transfers by value, for ==, whether it is comparing basic data types or referencing variables of data types, the essence of comparison is the value, but the value stored in the reference type variable is the address of the object.

equals() role of 160857cf205976 cannot be used to determine the basic data types of variables, but can only be used to determine whether two objects are equal. equals() method exists in the Object class, and the Object class is the direct or indirect parent of all classes.

Object category equals() method:

public boolean equals(Object obj) {
     return (this == obj);
}

There are two use cases for the equals()

  • class does not cover the equals() method : equals() comparing two objects of this class through 060857cf205a29, it is equivalent to comparing the two objects through "==". The default used is the Object class equals() method.
  • class covers the equals() method : generally we cover the equals() method to compare whether the attributes of two objects are equal; if their attributes are equal, return true (that is, the two objects are considered equal).

give an example:

public class test1 {
    public static void main(String[] args) {
        String a = new String("ab"); // a 为一个引用
        String b = new String("ab"); // b为另一个引用,对象的内容一样
        String aa = "ab"; // 放在常量池中
        String bb = "ab"; // 从常量池中查找
        if (aa == bb) // true
            System.out.println("aa==bb");
        if (a == b) // false,非同一对象
            System.out.println("a==b");
        if (a.equals(b)) // true
            System.out.println("aEQb");
        if (42 == 42.0) { // true
            System.out.println("true");
        }
    }
}

Description:

  • String in equals is being rewritten, as Object the equals is to compare the memory address of the object, and String the equals comparison are values of an object.
  • When creating String , the virtual machine looks for an object with the same value as the value to be created in the constant pool, and assigns it to the current reference if there is one. If not, create a new String object in the constant pool.

String category equals() method:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

hashCode() and equals()

The interviewer may ask you: "You rewritten hashcode and equals Why, why rewrite equals must be rewritten when hashCode method?"

1)hashCode() introduction:

hashCode() is to obtain a hash code, also known as a hash code; it actually returns an int integer. The function of this hash code is to determine the index position of the object in the hash table. hashCode() defined in the Object class of the JDK, which means that any class in Java contains the hashCode() function. Another thing to note is: Object is a native method, which is implemented in C language or C++. This method is usually used to convert the memory address of the object into an integer and then return.

public native int hashCode();

The hash table stores key-value pairs, and its characteristic is that it can quickly retrieve the corresponding "value" based on the "key". Among them, the hash code is used! (You can quickly find the object you need)

2) Why is there a hashCode?

We take " HashSet how to check for duplicates" as an example to illustrate why there is a hashCode?

When you add an object to HashSet , HashSet will first calculate the object's hashcode value to determine where the object is added, and also compare it with the hashcode values of other added objects. If there is no matching hashcode, HashSet will assume that the object is not duplicated. appear. But if objects with the same hashcode value are found, then the equals() method will be called to check whether the objects with equal hashcodes are really the same. If the two are the same, HashSet will not let it join successfully. If they are different, they will be re-hashed to another location. (Excerpt from my Java Enlightenment Book "Head First Java" Second Edition). In this way, we greatly reduce the number of equals, and accordingly greatly improve the execution speed.

3) Why rewrite equals must be rewritten when hashCode method?

If the two objects are equal, the hashcode must also be the same. The two objects are equal, and the equals method on the two objects respectively returns true. However, if two objects have the same hashcode value, they are not necessarily equal. Therefore, the equals method has been overridden, the hashCode method must also be overridden.

hashCode() is to generate unique values for objects on the heap. hashCode() is not rewritten, the two objects of the class will not be equal anyway (even if the two objects point to the same data)

4) Why do two objects have the same hashcode value, and they are not necessarily equal?

Explain the problem of a small partner here. The following content is taken from "Head Fisrt Java".

Because the hashCode() may just cause multiple objects to return the same hash value. The worse the hash algorithm is, the easier it is to collide, but this is also related to the characteristics of the data range distribution (the so-called collision means that different objects get the same hashCode .

We just mentioned HashSet . If HashSet has multiple objects in the same hashcode during comparison, it will use equals() to determine whether they are really the same. In other words, hashcode is only used to reduce the search cost.

For more information about hashcode() and equals() , please view: Java hashCode() and equals() answers to some questions

Basic data type

What are the basic data types in Java? What is the corresponding packaging type? How many bytes does each occupy?

There are 8 basic data types in Java, namely:

  1. 6 types of numbers: byte , short , int , long , float , double
  2. 1 character type: char
  3. 1 Boolean type: boolean .

The default values of these 8 basic data types and the size of the space occupied are as follows:

basic typeNumber of digitsbyteDefaults
int3240
short1620
long6480L
byte810
char162'u0000'
float3240f
double6480d
boolean1 false

In addition, for boolean , the official document is not clearly defined, it depends on the specific implementation of the JVM vendor. The logical understanding is to occupy 1 bit, but in practice, the computer's efficient storage factor will be considered.

Note:

  1. long data in Java, you L after the value, otherwise it will be parsed as an integer.
  2. char a = 'h' char: single quote, String a = "hello" : double quote.

These eight basic types have corresponding packaging categories: Byte , Short , Integer , Long , Float , Double , Character , Boolean .

The packaging type is Null it is not assigned, while the basic type has a default value and is not Null .

In addition, this problem suggestion can also be analyzed from the JVM level first.

The basic data types are directly stored in the local variable table in the Java virtual machine stack, and the packaging types are object types. We know that all object instances exist in the heap. Compared to object types, basic data types take up very little space.

"In-depth understanding of the Java virtual machine": The local variable table mainly stores the basic data types known at compile time (boolean, byte, char, short, int, float, long, double) , object reference (reference type, it Different from the object itself, it may be a reference pointer to the starting address of the object, or it may point to a handle representing the object or other locations related to the object).

Automatic boxing and unboxing

  • Packing : Pack the basic types with their corresponding reference types;
  • Unboxing : Convert the packaging type to a basic data type;

For example:

Integer i = 10;  //装箱
int n = i;   //拆箱

The bytecode corresponding to the above two lines of code is:

   L1

    LINENUMBER 8 L1

    ALOAD 0

    BIPUSH 10

    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;

    PUTFIELD AutoBoxTest.i : Ljava/lang/Integer;

   L2

    LINENUMBER 9 L2

    ALOAD 0

    ALOAD 0

    GETFIELD AutoBoxTest.i : Ljava/lang/Integer;

    INVOKEVIRTUAL java/lang/Integer.intValue ()I

    PUTFIELD AutoBoxTest.n : I

    RETURN

From the bytecode, we find that boxing is actually calling the valueOf() method of the packaging class, and unboxing is actually calling the xxxValue() method.

therefore,

  • Integer i = 10 equivalent to Integer i = Integer.valueOf(10)
  • int n = i equivalent to int n = i.intValue() ;

8 basic types of packaging classes and constant pools

Most of the wrapper classes of Java basic types implement constant pool technology. Byte , Short , Integer , Long these four wrapper class is created by default values [-128,127] corresponding type of cache data, Character created cache data values in the range [0,127] is, Boolean returned directly True Or False .

Integer cache source code:

/**

*此方法将始终缓存-128 到 127(包括端点)范围内的值,并可以缓存此范围之外的其他值。

*/

public static Integer valueOf(int i) {

    if (i >= IntegerCache.low && i <= IntegerCache.high)

      return IntegerCache.cache[i + (-IntegerCache.low)];

    return new Integer(i);

}

private static class IntegerCache {

    static final int low = -128;

    static final int high;

    static final Integer cache[];

}

Character Cache source code:

public static Character valueOf(char c) {

    if (c <= 127) { // must cache

      return CharacterCache.cache[(int)c];

    }

    return new Character(c);

}



private static class CharacterCache {

    private CharacterCache(){}



    static final Character cache[] = new Character[127 + 1];

    static {

        for (int i = 0; i < cache.length; i++)

            cache[i] = new Character((char)i);

    }

}

Boolean Cache source code:

public static Boolean valueOf(boolean b) {

    return (b ? TRUE : FALSE);

}

If it exceeds the corresponding range, it will still create new objects. The size of the cache range is only a trade-off between performance and resources.

The two types of floating-point number packaging classes Float and Double do not implement the constant pool technology.

Integer i1 = 33;

Integer i2 = 33;

System.out.println(i1 == i2);// 输出 true

Float i11 = 333f;

Float i22 = 333f;

System.out.println(i11 == i22);// 输出 false

Double i3 = 1.2;

Double i4 = 1.2;

System.out.println(i3 == i4);// 输出 false

Let's look at the problem below. Is the output of the following code true or flase ?

Integer i1 = 40;

Integer i2 = new Integer(40);

System.out.println(i1==i2);

Integer i1=40 line of code will be unboxed, which means that this line of code is equivalent to Integer i1=Integer.valueOf(40) . Therefore, i1 directly uses objects in the constant pool. And Integer i1 = new Integer(40) will directly create new objects.

Therefore, the answer is false . Did you get it right?

Remember: all integer package object value comparisons, all use the equals method to compare .

Method (function)

What is the return value of the method?

The return value of a method refers to the result of the execution of the code in a certain method body we obtained! (The premise is that the method may produce results). The function of the return value is to receive the result so that it can be used for other operations!

What are the types of methods?

1. Method with no parameters and no return value

// 无参数无返回值的方法(如果方法没有返回值,不能不写,必须写void,表示没有返回值)
public void f1() {
    System.out.println("无参数无返回值的方法");
}

2. Method with parameters and no return value

/**
* 有参数无返回值的方法
* 参数列表由零组到多组“参数类型+形参名”组合而成,多组参数之间以英文逗号(,)隔开,形参类型和形参名之间以英文空格隔开
*/
public void f2(int a, String b, int c) {
    System.out.println(a + "-->" + b + "-->" + c);
}

3. Method with return value and no parameters

// 有返回值无参数的方法(返回值可以是任意的类型,在函数里面必须有return关键字返回对应的类型)
public int f3() {
    System.out.println("有返回值无参数的方法");
    return 2;
}

4. Methods with return values and parameters

// 有返回值有参数的方法
public int f4(int a, int b) {
    return a * b;
}

5.return Special use of methods without return value

// return在无返回值方法的特殊使用
public void f5(int a) {
    if (a > 10) {
        return;//表示结束所在方法 (f5方法)的执行,下方的输出语句不会执行
    }
    System.out.println(a);
}

Why is it illegal to call a non-static member in a static method?

This needs to be combined with the relevant knowledge of the JVM. The static method belongs to the class, and memory is allocated when the class is loaded, and it can be directly accessed through the class name. Non-static members belong to the instance object, only exist after the object is instantiated, and then accessed through the instance object of the class. The static member already exists when the non-static member of the class does not exist. At this time, calling the non-static member that does not exist in the memory is an illegal operation.

What is the difference between static methods and instance methods?

  1. When calling a static method externally, you can use the "class name. method name" method or the "object name. method name" method. The instance method has only the latter way. In other words, call a static method without creating an object.
  2. When static methods access the members of this class, they only allow access to static members (ie, static member variables and static methods), but not instance member variables and instance methods; instance methods have no such restriction.

Why is there only value passing in Java?

First, let's review some professional terms related to passing parameters to methods (or functions) in programming languages.

call by value indicates that the method receives the value by the caller indicates that the method receives the variable address provided by the caller. A method can modify the value of the variable corresponding to the passed reference, but cannot modify the value of the variable corresponding to the passed value call. It is used to describe the method parameter passing method in various programming languages (not just Java).

Java programming language always uses call by value. In other words, the method gets a copy of all parameter values, that is, the method cannot modify the contents of any parameter variables passed to it.

Here are three examples to illustrate

example 1
public static void main(String[] args) {
    int num1 = 10;
    int num2 = 20;

    swap(num1, num2);

    System.out.println("num1 = " + num1);
    System.out.println("num2 = " + num2);
}

public static void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;

    System.out.println("a = " + a);
    System.out.println("b = " + b);
}

result:

a = 20
b = 10
num1 = 10
num2 = 20

resolved:

example 1

In the swap method, the values of a and b are exchanged, and num1 and num2 are not affected. Because the values in a and b are just copied from num1 and num2. In other words, a and b are equivalent to copies of num1 and num2, and no matter how the content of the copy is modified, it will not affect the original itself.

Through the above example, we already know that a method cannot modify a parameter of a basic data type, and the object reference as a parameter is different, please see example2.

example 2
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5 };
        System.out.println(arr[0]);
        change(arr);
        System.out.println(arr[0]);
    }

    public static void change(int[] array) {
        // 将数组的第一个元素变为0
        array[0] = 0;
    }

result:

1
0

resolved:

example 2

The copy of array initialized arr is also a reference to an object, that is to say, array and arr point to the same array object. Therefore, external changes to the referenced object will be reflected on the corresponding object.

Through example2, we have seen that it is not difficult to implement a method to change the state of an object parameter. The reason is simple, the method gets a copy of the object reference, and the object reference and other copies refer to the same object at the same time.

Many programming languages (especially, C++ and Pascal) provide two ways to pass parameters: value call and reference call. Some programmers (even the author of this book) think that the Java programming language uses reference calls to objects. In fact, this understanding is wrong. Because this misunderstanding has a certain generality, a counterexample is given below to elaborate on this problem.

example 3
public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Student s1 = new Student("小张");
        Student s2 = new Student("小李");
        Test.swap(s1, s2);
        System.out.println("s1:" + s1.getName());
        System.out.println("s2:" + s2.getName());
    }

    public static void swap(Student x, Student y) {
        Student temp = x;
        x = y;
        y = temp;
        System.out.println("x:" + x.getName());
        System.out.println("y:" + y.getName());
    }
}

result:

x:小李
y:小张
s1:小张
s2:小李

resolved:

Before the exchange:

After the exchange:

It can be clearly seen from the above two pictures: method does not change the object references stored in the variables s1 and s2. The parameters x and y of the swap method are initialized as copies of two object references. This method exchanges these two copies

summary

The Java programming language does not use reference calls to objects. In fact, object references are based on
By value.

Let's summarize the usage of method parameters in Java:

  • A method cannot modify a parameter of a basic data type (ie, numeric or boolean).
  • A method can change the state of an object parameter.
  • A method cannot let the object parameter refer to a new object.

Reference:

"Java Core Technology Volume Ⅰ" Basic Knowledge, Tenth Edition, Chapter 4, Section 4.5

The difference between overloading and rewriting

Overloading is the same method that can make different processing according to the different input data

Overriding is when the subclass inherits the same method from the parent class, the input data is the same, but when you want to make a response different from the parent class, you have to override the parent class method

Overload

Occurs in the same class (or between the parent class and the subclass), the method name must be the same, the parameter types are different, the number is different, the order is different, and the method return value and access modifier can be different.

The following is an introduction to the concept of overloading in "Java Core Technology":

To sum up: Overloading means that multiple methods with the same name in the same class perform different logical processing according to different passed parameters.

Rewrite

Rewriting occurs at runtime, and is the process of rewriting the implementation of the accessible methods of the parent class by the subclass.

  1. The return value type, method name, and parameter list must be the same, the thrown exception range is less than or equal to the parent class, and the access modifier range is greater than or equal to the parent class.
  2. If the parent class method access modifier is private/final/static , the subclass cannot override the method, but the method modified by static can be declared again.
  3. The constructor cannot be overridden

To sum up: Rewriting is the re-transformation of the method of the parent class by the subclass. The external appearance cannot be changed, and the internal logic can be changed.

Heart-warming Guide, let’s finally summarize it with a chart!

DifferenceOverloaded methodRewrite method
Scope of occurrenceSame classSubclass
parameter listMust be modifiedMust not be modified
Return typeCan be modifiedThe return value type of the subclass method should be smaller or equal to the return value type of the parent method
abnormalCan be modifiedThe exception class thrown by the subclass method declaration should be smaller or equal to the exception class thrown by the parent class method declaration;
Access modifierCan be modifiedMust not make stricter restrictions (restrictions can be lowered)
Occurrence stageCompile timeRuntime

method should follow the "two same two small one big" (the following content is excerpted from "Crazy Java Lecture Notes", issue#892 ):

  • "Two same" means that the method name is the same and the parameter list is the same;
  • "Two small" means that the return value type of the subclass method should be smaller or equal than the return value type of the parent method, and the exception class thrown by the subclass method declaration should be smaller or equal to the exception class thrown by the parent method declaration. ;
  • "One big" means that the access rights of the subclass methods should be greater or equal to the access rights of the parent class methods.

⭐️ Regarding the rewritten return value class type, we need to explain more. The above statement is not clear and accurate: if the return type of the method is void and basic data type, the return value cannot be modified when rewritten. But if the return value of the method is a reference type, it is possible to return a subclass of the reference type when overridden.

public class Hero {
    public String name() {
        return "超级英雄";
    }
}
public class SuperMan extends Hero{
    @Override
    public String name() {
        return "超人";
    }
    public Hero hero() {
        return new Hero();
    }
}

public class SuperSuperMan extends SuperMan {
    public String name() {
        return "超级超级英雄";
    }

    @Override
    public SuperMan hero() {
        return new SuperMan();
    }
}

Deep copy vs. shallow copy

  1. shallow copy : the basic data type is passed by value, and the reference data type is copied by reference. This is a shallow copy.
  2. deep copy : transfer basic data types by value, create a new object for reference data types, and copy its content, this is a deep copy.

deep and shallow copy

Java Object Oriented

The difference between object-oriented and process-oriented

  • process-oriented : process-oriented performance is higher than object-oriented. needs to be instantiated when the class is called, which is relatively expensive and consumes resources. Therefore, when performance is the most important consideration, such as single-chip microcomputer, embedded development, Linux/Unix, etc., generally adopt process-oriented development. However, process-oriented is not object-oriented, easy to maintain, easy to reuse, and easy to extend.
  • object-oriented : object-oriented easy to maintain, easy to reuse, easy to expand. Because object-oriented has the characteristics of encapsulation, inheritance, and polymorphism, a low-coupling system can be designed to make the system more flexible and easier to maintain. However, object-oriented performance lower than the process-oriented .

See issue: Process-oriented: Process-oriented performance is higher than object-oriented? ?

This is not the root cause. Process-oriented also needs to allocate memory and calculate memory offset. The main reason for the poor performance of Java is not because it is an object-oriented language, but because Java is a semi-compiled language, and the final execution code cannot be directly executed. Binary mechanical code executed by the CPU.

Most of the process-oriented languages are directly compiled into machine code and executed on the computer, and the performance of other process-oriented scripting languages is not necessarily better than that of Java.

What are the differences between member variables and local variables?

  1. From the perspective of grammatical form, member variables belong to classes, and local variables are variables defined in code blocks or methods or method parameters; member variables can be modified by modifiers such as public , private , static It cannot be modified by access control modifiers and static ; however, member variables and local variables can be modified final
  2. From the perspective of how the variable is stored in the memory, if the member variable is static , then the member variable belongs to the class. If it is not static , the member variable belongs to the instance. Objects exist in heap memory, and local variables exist in stack memory.
  3. From the point of view of the survival time of variables in memory, member variables are part of the object. They exist with the creation of the object, and local variables disappear automatically with the call of the method.
  4. From the point of view of whether the variable has a default value, if the member variable is not assigned, it will be automatically assigned with the default value of the type (an exception: final must also be assigned explicitly), and local variables It will not be automatically assigned.

What operator is used to create an object? What is the difference between an object entity and an object reference?

The new operator, new creates an object instance (the object instance is in the heap memory), and the object reference points to the object instance (the object reference is stored in the stack memory).

An object reference can point to 0 or 1 object (a rope may not be tied to a balloon, or it can be tied to a balloon); an object can have n references to it (a balloon can be tied to n ropes).

The equality of objects is equal to the reference to them. What is the difference between the two?

The equality of objects is compared to whether the contents stored in the memory are equal. While the references are equal, the comparison is whether the memory addresses they point to are equal.

What is the role of a class's constructor? If a class does not declare a constructor, can the program be executed correctly? Why?

The main function of the construction method is to complete the initialization of the class object.

If a class does not declare a constructor, it can be executed! Because even if a class does not declare a constructor, there will be a default constructor without parameters. If we add the construction method of the class ourselves (regardless of whether there are parameters), Java will no longer add the default no-parameter construction method. At this time, we can't directly new an object without passing parameters, so we have been Unknowingly use the constructor, which is why we have to add a parenthesis when creating the object (because we need to call the constructor without parameters). If we overload the construction method with parameters, remember to also write the construction method without parameters (regardless of whether it is used or not), because this can help us avoid pitfalls when creating objects.

What are the characteristics of the construction method? Can it be overridden?

Features:

  1. The name is the same as the class name.
  2. There is no return value, but the constructor cannot be declared with void.
  3. It is automatically executed when the object of the class is generated, without calling.

The constructor cannot be overridden, but it can be overloaded, so you can see that there are multiple constructors in a class.

Three characteristics of object-oriented

Encapsulation

Encapsulation refers to hiding the state information (that is, attributes) of an object inside the object, and not allowing external objects to directly access the internal information of the object. However, it is possible to provide some methods that can be accessed by the outside world to manipulate attributes. It's as if we can't see the internal part information (that is, attributes) of the air conditioner hung on the wall, but the air conditioner can be controlled by the remote control (method). If the property does not want to be accessed by the outside world, we do not need to provide a method for outside access. But if a class does not provide methods for outside access, then this class has no meaning. It's like if there is no air conditioner remote control, then we can't control the air conditioner, the air conditioner itself is meaningless (of course there are many other methods, here is just for example).

public class Student {
    private int id;//id属性私有化
    private String name;//name属性私有化

    //获取id的方法
    public int getId() {
        return id;
    }

    //设置id的方法
    public void setId(int id) {
        this.id = id;
    }

    //获取name的方法
    public String getName() {
        return name;
    }

    //设置name的方法
    public void setName(String name) {
        this.name = name;
    }
}

inherit

Different types of objects often have a certain amount in common with each other. For example, Xiao Ming, Xiao Hong, and Xiao Li all share the characteristics of students (class, student number, etc.). At the same time, each object also defines additional characteristics that make them unique. For example, Xiao Ming's math is better, Xiao Hong's personality is lovable; Xiao Li's strength is stronger. Inheritance is a technology that uses the definition of an existing class as a basis to create a new class. The definition of a new class can add new data or new functions, or use the functions of the parent class, but it cannot selectively inherit the parent class. By using inheritance, new classes can be created quickly, code reuse, program maintainability can be improved, a lot of time for creating new classes can be saved, and our development efficiency can be improved.

Please remember the following 3 points about inheritance:

  1. The subclass has all the properties and methods of the parent class object (including private properties and private methods), but the private properties and methods in the parent class are not accessible by the .
  2. Subclasses can have their own properties and methods, that is, subclasses can extend the parent class.
  3. Subclasses can implement the methods of the parent class in their own way. (Introduced later).

Polymorphism

Polymorphism, as the name implies, means that an object has multiple states. Specifically, the reference of the parent class points to the instance of the child class.

polymorphism:

  • There is an inheritance (class)/implementation (interface) relationship between object types and reference types;
  • The method in which the method issued by the reference type variable calls the method in which class must be determined during the running of the program;
  • Polymorphism cannot call the method "only exists in the child class but not in the parent class";
  • If the subclass overrides the method of the parent class, the method that the subclass overrides is actually executed. If the subclass does not override the method of the parent class, the method of the superclass is executed.

What is the difference between String StringBuffer and StringBuilder? Why is String immutable?

Variability

Simply put: String uses the final keyword to modify the character array to save the string, private final char value[] , so the String object is immutable.

Supplement (from issue 675 ): After Java 9, StringBuilder and StringBuffer uses byte array to store string private final byte[] value

And StringBuilder and StringBuffer both inherit from the AbstractStringBuilder class. In AbstractStringBuilder , the character array is also used to save the string char[]value but it is not final keyword, so these two objects are variable.

StringBuilder and StringBuffer are implemented by calling the parent construction method, which is AbstractStringBuilder . You can check the source code by yourself.

AbstractStringBuilder.java

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;

    /**
     * The count is the number of characters used.
     */
    int count;

    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }}

thread safety

String are immutable, which can be understood as constants and thread-safe. AbstractStringBuilder is StringBuilder and StringBuffer , which defines some basic operations of strings, such as expandCapacity , append , insert , indexOf and other public methods. StringBuffer a synchronization lock to the method or adds a synchronization lock to the called method, so it is thread-safe. StringBuilder does not add a synchronization lock to the method, so it is not thread-safe.

Performance

Every time the String type is changed, a new String object will be generated, and then the pointer will point to the new String object. StringBuffer will operate on the StringBuffer object itself every time, instead of generating new objects and changing object references. In the same situation, using StringBuilder can only obtain a performance improvement of about 10%~15% compared to using StringBuffer

summarizes the use of the three:

  1. Operate a small amount of data: apply String
  2. Operate a large amount of data in a single-threaded string buffer: applicable to StringBuilder
  3. Operate large amounts of data under multi-threaded operation string buffer: applicable to StringBuffer

Summary of common methods of the Object class

The Object class is a


JavaGuide
9k 声望1.9k 粉丝

你好,我是 Guide,开源项目 JavaGuide 作者。