JavaSE basic issues

1, The difference between & and &&?

The & operator is: logical and; && operator is: short-circuit and.

The final operation results of & and && in the program are exactly the same, but && has a short-circuit phenomenon. When the result of the expression on the left of the && operator is false, the expression on the right is not executed, and a short-circuit occurs. . If it is the & operator, then no matter whether the expression on the left is true or false, the expression on the right will definitely be executed. This is the essential difference between the two of them.

3. Two objects with the same value equals result in true, but they can have different hashCodes. Is this sentence correct?

No, if two objects x and y satisfy x.equals(y) == true, their hash values ​​(hashCode) should be the same. Java stipulates the equals method and the hashCode method as follows:

(1) If two objects are the same (equals method returns true), then their hashCode values ​​must be the same;

(2) If the hashCode of two objects is the same, they are not necessarily the same. Of course, you may not follow the requirements, but if you violate the above principles, you will find that when using the set, the same object can appear in the Set collection, and the efficiency of adding new elements will be greatly reduced (for the use of hash storage System, if the hash code conflicts frequently, the access performance will drop sharply).

Regarding equals and hashCode methods, many Java programmers know, but many people just understand it. In Joshua Bloch’s masterpiece "Effective Java" ("Effective Java" is a must-read book for Java programmers in many companies, if you Haven't read it yet, so hurry up and buy one) The equals method is introduced in this way:

First of all, the equals method must satisfy reflexivity (x.equals(x) must return true), symmetry (when x.equals(y) returns true, y.equals(x) must also return true), and transitivity (x. When equals(y) and y.equals(z) both return true, x.equals(z) must also return true) and consistency (when the object information referenced by x and y has not been modified, call x.equals multiple times (y) should get the same return value), and for any non-null value reference x, x.equals(null) must return false. The tricks to achieve a high-quality equals method include:

Use == operator to check "whether the parameter is a reference to this object";

Use the instanceof operator to check "whether the parameter is of the correct type";

For the key attributes in the class, check whether the attributes of the parameter passed into the object match it;

After writing the equals method, ask yourself whether it meets symmetry, transitivity, and consistency;

Always rewrite hashCode when rewriting equals;

Do not replace the Object object in the equals method parameters with other types, and do not forget the @Override annotation when rewriting.

4. How to break out of the current multiple nested loops in Java?

Add a mark such as outfor before the outermost loop, and then use break outfor; to jump out of multiple loops. For example, the following code:


public class TestBreak {
    
    
    public static void main(String[] args) {
    
    
        outfor: for (int i = 0; i < 10; i++){
    
    
            for (int j = 0; j < 10; j++){
    
    
                if (j == 5){
    
    
                    break outfor;
                }
                System.out.println("j = " + j);
            }
        }
    }
}

5. What is the difference between overload and override? Can overloaded methods be distinguished based on the return type?

Method overloading and rewriting are both ways to achieve polymorphism. The difference is that the former implements polymorphism at compile time, while the latter implements polymorphism at runtime.

Overloading occurs in a class, and methods with the same name are considered overloaded if they have different parameter lists (different types, different numbers, and different orders).

Overriding occurs between the subclass and the parent class. The overriding requires that the method after the subclass override has the same return type as the overridden method of the parent class, which is better than the overridden method of the parent class, and cannot be compared The overridden method declares more exceptions (Liskov Substitution Principle). Overloading has no special requirements for the return type.

● Rules for method overloading:

The method names are the same, and the order, type, and number of parameters in the parameter list are different.

Overloading has nothing to do with the return value of the method, and exists in the parent class and subclass, in the same category.

Different exceptions can be thrown, and there can be different modifiers.

● Rules for method rewriting:

The parameter list, method name, and return value type must be completely consistent;

The construction method cannot be rewritten;

The method declared as final cannot be overridden;

There is no overriding of the method declared as static (rewriting and polymorphic union only make sense);

The access authority cannot be lower than the parent class;

The method after rewriting cannot throw a broader exception;

6. When an object is passed as a parameter to a method, the method can change the properties of the object and return the changed result. So, is it passed by value or by reference?

It is value transfer. Method calls in the Java language only support parameter value passing. When an object instance is passed to the method as a parameter, the value of the parameter is the memory address of the object. After this value (memory address) is passed, the same memory address points to the same object in the heap memory, so by which reference to manipulate this object, the properties of the object are changed.

7. Why can't methods distinguish overloads based on return type?

Let's look at the following code:

public void testMethod(){
doSome();
}
public void doSome(){

}
public int doSome(){
return 1;
}

In the Java language, if a method is called, even if the method has a return value, we can also not receive the return value. For example, the above two methods doSome(), when called in testMethod(), the Java compiler cannot distinguish the called Which method is specific. So for the compiler, the doSome() method is not overloaded but repeated, and the compiler reports an error. Therefore, the distinction between these two methods cannot rely on the return value type of the method.

8. What are the similarities and differences between abstract class and interface?

both are not.

● Abstract methods need to be rewritten by subclasses, while static methods cannot be rewritten, so the two are contradictory.

● Native methods are methods implemented by native codes (such as C++ code), while abstract methods are not implemented and contradictory.

● Synchronized is related to the implementation details of the method. Abstract methods do not involve the implementation details, so they are contradictory.

9. Can a Chinese character be stored in a char variable? Why?

The char type can store a Chinese character, because the encoding used in Java is Unicode (do not choose any specific encoding, directly use the number of the character in the character set, this is the only way to unify), a char type occupies 2 bytes ( 16 bits), so it’s no problem to put a Chinese.

Supplement: Using Unicode means that characters have different manifestations inside and outside the JVM. Inside the JVM, they are all Unicode. When this character is transferred from inside the JVM to the outside (such as stored in the file system), encoding conversion is required. So there are byte streams and character streams in Java, as well as conversion streams that convert between character streams and byte streams, such as InputStreamReader and OutputStreamReader. These two classes are adapter classes between byte streams and character streams. The task of code conversion.

10. Can abstract methods be static at the same time, can they be native methods at the same time, and can they be synchronized at the same time?

both are not.

● Abstract methods need to be rewritten by subclasses, while static methods cannot be rewritten, so the two are contradictory.

● Native methods are methods implemented by native codes (such as C++ code), while abstract methods are not implemented and contradictory.

● Synchronized is related to the implementation details of the method. Abstract methods do not involve the implementation details, so they are contradictory.

11. What is the difference between == and equals?

The biggest difference between equals and == is that one is the method and the other is the operator.

● ==: If the compared object is a basic data type, the comparison is whether the value is equal; if the comparison is a reference data type, the comparison is whether the address value of the object is equal.

● equals(): used to compare whether the contents of the two objects of the method are equal. The equals method cannot be used for variables of basic data types. If the equals method is not rewritten, the address of the object pointed to by the variable of the reference type is compared.

12. Explain the difference between static variables and instance variables?

No matter how many objects are created, there is one and only one static variable in the memory; the instance variable must depend on an instance, and the object needs to be created and then accessed through the object. Static variables can be implemented to allow multiple objects to share memory.

13. What is the difference between break and continue?

● break and continue are statements used to control loops.

● break is used to completely end a loop, jump out of the loop body and execute the statement following the loop.

continue is used to skip this cycle and continue to the next cycle.

14. String s = "Hello"; s = s + "world!"; After these two lines of code are executed, has the content of the original String object changed?

No.

Because String is designed as an immutable class, all its objects are immutable objects.

In this code, s originally pointed to a String object with the content "Hello", and then we performed a "+" operation on s. Has the object pointed to by s changed?

The answer is no. At this time, s does not point to the original object, but points to another String object with the content "Hello world!". The original object still exists in the memory, but the reference variable s no longer points to it.

Through the above description, we can easily derive another conclusion. If you often make various modifications to the string, or unforeseen modification, then using String to represent the string will cause a lot of memory overhead. Because the String object cannot be changed after it is created, a String object is needed to represent each different string. At this time, you should consider using the StringBuffer/StringBuilder class, which allows modification instead of generating a new object for each different string. Moreover, the conversion of these two types of objects is very easy. At the same time, we can also know that if you want to use a string with the same content, you don't need to new a String every time. For example, if we want to initialize a String reference variable named s in the constructor and set it to the initial value, we should do this:

s = new String("Power node, the Java Whampoa Military Academy of word of mouth");

Instead of doing this:

s = new String("Power node, the Java Whampoa Military Academy of word of mouth");

The latter will call the constructor every time to generate a new object, which has low performance and high memory overhead, and is meaningless, because the String object cannot be changed, so for a string with the same content, only one String object can be used to represent it. In other words, if the above constructor is called multiple times to create multiple objects, their String type properties all point to the same object.

The above conclusion is also based on the fact that for string constants, if the content is the same, Java considers them to represent the same String object. Invoking the constructor with the keyword new will always create a new object, regardless of whether the content is the same.

As for why the String class is designed as an immutable class, it is determined by its purpose. In fact, not only String, but many classes in the Java standard library are immutable. When developing a system, we sometimes need to design immutable classes to pass a set of related values, which is also a manifestation of object-oriented thinking. Immutable classes have some advantages. For example, because its objects are read-only, there is no problem with concurrent access by multiple threads. Of course, there are some shortcomings. For example, each different state must be represented by an object, which may cause performance problems. Therefore, the Java Standard Class Library also provides a variable version, namely StringBuffer.

Guess you like

Origin blog.csdn.net/weixin_38019299/article/details/108084495