Just experienced the autumn recruit, read a lot of interviews, by the way will be common Java often test knowledge summarized, and according to the frequency of being asked to roughly do a mark. One star means knowledge needs to be understood, not frequently asked, at least about the interview. Two stars indicate that you are asked frequently or are important to understanding Java. Proficiency is recommended. Three stars means that the frequency of being asked is very high. It is recommended to deeply understand and master relevant knowledge, which is convenient to expand during the interview (convenient to act like a force) and leave a good impression on the interviewer.

Search the public account zhang on wechat, reply to the interview manual, and get the PDF version of this document and more interview materials.

Understand all the HashMap interview questions

The relationship between JVM, JRE, and JDK * *

The Java Development Kit (JDK) is a product for Java developers. It is the core of the entire Java, including the Java runtime environment (JRE), Java tools, and Java basic class libraries.

The Java Runtime Environment (JRE) is a collection of environments necessary to run Java programs, including the JVM standard implementation and Java core class libraries.

JVM is the abbreviation of Java Virtual Machine (Java Virtual Machine), is the core part of the entire Java implementation cross-platform, can run software programs written in the Java language.

In simple terms, the JDK is the Java development tool, the JRE is the environment required by the Java program, and the JVM is the Java virtual machine. The relationship is that the JDK contains the JRE and the JVM, and the JRE contains the JVM.

JAVA language features * *

  • Java is an object-oriented language
  • Java implements platform independence through the Java Virtual machine, compiling once and running anywhere
  • Multithreading support
  • Support network programming
  • It has high security and reliability

The difference between JAVA and C++ * *

Just remember the first four for the interview

  • Java implements cross-platform features through virtual machines, but C++ is platform-specific.
  • Java has no Pointers, and its references can be understood as safe Pointers, whereas C++ has the same Pointers as C.
  • Java supports automatic garbage collection, while C++ requires manual collection.
  • Java does not support multiple inheritance and can only implement multiple interfaces to achieve the same goal, while C++ does.
  • Java does not support operator overloading, and while it is possible to add two strings, this is supported by the language and not operator overloading, whereas C++ does.
  • Java’s goto is reserved but not available. C++ can use goto.

Java basic data types * *

Note that String is not a basic data type

type The keyword Wrapper type Memory Occupied (bytes)important) Value range The default value
Byte type byte Byte 1 127-128-2 ^ (7) ~ (2 ^ 7-1) 0
Short integer short Short 2 15 ~ 2-2 ^ ^ 15-1 0
The integer int Integer 4 – 2 ^ 31 ~ 2 ^ 31-1 0
Long integer long Long 8 – 2 ^ 63 ~ 2 ^ 63-1 0L
Single-precision floating point type float Float 4 3.4 e-45 ~ 1.4 e38 0.0 F
A double precision floating point type double Double 8 E308 e-324 4.9 ~ 1.8 0.0 D
character char Character 2 ‘\u0000’
The Boolean boolean Boolean 1 true/flase flase

Implicit (automatic) type conversions and display (forced) type conversions * *

  • Implicit (automatic) type conversion: from a type with a small storage range to a type with a large storage range.byteshort(char)intlongfloatdouble
  • Show (force) type conversions: from a type with a large storage range to a type with a small storage range.doublefloatlongintshort(char)byte. This type conversion is likely to have a loss of precision.

Let’s look at a classic code

short s = 1;
s = s + 1;
Copy the code

This is an error because 1 is an int, s+1 is automatically converted to an int, and assigning an int directly to a short is an error.

Make a change to avoid errors

short s = 1;
s = (short)(s + 1);
Copy the code

Or write it this way, because s += 1 is automatically cast

short s = 1;
s += 1;
Copy the code

Automatic packing and unpacking

  • Boxing: Base types are wrapped in wrapper types

  • Unpacking: Converts wrapper type to base type

    There are a lot of confusing things about this, but it is often asked in interviews, and often used in multiple-choice questions in written exams. There is also a String creation object that is similar to this, which is easy to confuse, as you can see below

  • What is the output of the following code?

    public class Main {
        public static void main(String[] args) {
            
                Integer a = 100;
                Integer b = 100;
                Integer c = 128;
                Integer d = 128; System.out.println(a==b); System.out.println(c==d); }}Copy the code
    true
    false
    Copy the code

    Many people will wonder why it is true and flase when they see this result. In fact, it is easy to find the reason from the source code. Start by finding the valueOf method in the Integer method

    public static Integer valueOf(int i) {
          if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
          return new Integer(i);
      }
    Copy the code

    As you can see, when the condition in the if statement is not met, a new object is created to return, and the result must not be equal. Open IntegerCache and you can see

        private static class IntegerCache {
              static final int low = -128;
            static final int high;
              static final Integer cache[];
      
              static {
                  // high value may be configured by property
                  int h = 127;
                  String integerCacheHighPropValue =
                      sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                  if(integerCacheHighPropValue ! =null) {
                      try {
                          int i = parseInt(integerCacheHighPropValue);
                          i = Math.max(i, 127);
                          // Maximum array size is Integer.MAX_VALUE
                          h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                      } catch( NumberFormatException nfe) {
                          // If the property cannot be parsed into an int, ignore it.
                      }
                  }
                  high = h;
      
                  cache = new Integer[(high - low) + 1];
                  int j = low;
                  for(int k = 0; k < cache.length; k++)
                      cache[k] = new Integer(j++);
      
                  // range [-128, 127] must be interned (JLS7 5.1.7)
                  assert IntegerCache.high >= 127;
              }
      
              private IntegerCache(a) {}}Copy the code

    If the valueOf an Integer is between [-128,127], it returns a reference to an existing object in integercache. cache. Otherwise, a new Integer object is created. So in the code above, a is equal to B and C is not equal to D.

  • What does the following code output

    public class Main {
        public static void main(String[] args) {
    
                Double a = 1.0;
                Double b = 1.0;
                Double c = 2.0;
                Double d = 2.0; System.out.println(a==b); System.out.println(c==d); }}Copy the code
    flase
    flase
    Copy the code

    Using the same method, you can see that the valueOf method of Double returns a new object each time, so the result in the above code does not want to wait.

    public static Double valueOf(double d) {
              return new Double(d);
    }
    Copy the code
  • Finally, look at the output of this code

    public class Main {
        public static void main(String[] args) {
    
            Boolean a = false;
            Boolean b = false;
            Boolean c = true;
            Boolean d = true; System.out.println(a==b); System.out.println(c==d); }}Copy the code
    true
    true
    Copy the code

    The old method continues with the valueOf method

    public static Boolean valueOf(boolean b) {
            return (b ? TRUE : FALSE);
        }
    Copy the code

    Let’s see what TRUE and FALSE are. They’re static member properties.

    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);
    Copy the code

The implementation of valueOf methods for Integer, Short, Byte, Character, and Long is similar. The implementation of valueOf methods for Double and Float is similar. And then the Boolean valueOf methods are a separate set.

  • Integer I = new Integer(XXX) Integer I = XXX

    The main difference between the two is that the first will trigger automatic boxing, the second two will not

    Finally, look at the output of the following program

    public class Main {
        public static void main(String[] args) {
            Integer a = 1;
            Integer b = 2;
            Integer c = 3;
            Long g = 3L;
            int int1 = 12;
            int int2 = 12;
            Integer integer1 = new Integer(12);
            Integer integer2 = new Integer(12);
            Integer integer3 = new Integer(1);
    
            System.out.println("c==(a+b) ->"+ (c==(a+b)));
            System.out.println("g==(a+b) ->" + (g==(a+b)));
            System.out.println( "c.equals(a+b) ->" + (c.equals(a+b)));
            System.out.println( "g.equals(a+b) ->" + (g.equals(a+b)));
            System.out.println("int1 == int2 -> " + (int1 == int2));
            System.out.println("int1 == integer1 -> " + (int1 == integer1));
            System.out.println("integer1 == integer2 -> " + (integer1 == integer2));
            System.out.println("integer3 == a1 -> "+ (integer3 == a)); }}Copy the code
    c==(a+b) ->true
    g==(a+b) ->true
    c.equals(a+b) ->true
    g.equals(a+b) ->false
    int1 == int2 -> true
    int1 == integer1 -> true
    integer1 == integer2 -> false
    integer3 == a1 -> false
    Copy the code

    The following is a brief explanation of these results.

    1. When both operands of the “==” operator are references to wrapper types, the comparison refers to the same object, whereas if one of the operands is an expression (that is, contains an arithmetic operation), the comparison is numeric (that is, triggers automatic unboxing). So c==a+b, g==a+b is true.

    2. The equals method triggers the automatic unpacking process first and then the automatic packing process. A + B will call intValue and then call Integer.valueOf to compare equals. So c. quals(a+b) is true. For G.als (a+b), a+ B will be unpacked to add and compared to equals. But after packing, it is Integer and g is Long, so G.als (a+b) is false.

    Int1 == Int2 = true; int1 == integer1; int1 == integer1;

    4. Integer1 == Integer2 -> False. Both integer1 and integer2 are created using the new keyword and can be regarded as two objects. Therefore, integer1 == Integer2 is false. Integer3 == a1 -> false. Integer3 is an object type, and a1 is a constant. They store memory in different locations.

String(not base data type)

Immutability of String * * *

In Java 8, strings use char arrays internally to store data. And is declared final, so it cannot be inherited.

public final class String implements java.io.Serializable.Comparable<String>, CharSequence {	
	private final char value[];
}
Copy the code

Why should strings be designed to be immutable (immutability benefits) :

1. Can cache hash values ()

Because String hash values are often used, for example String is used as the key of a HashMap. The immutable nature makes the hash value immutable, so it only needs to be evaluated once.

2. Constant pool optimization

After the String object is created, it is cached in the String constant pool, and the next time the same object is created, the cached reference is returned directly.

3. Thread safety

String immutability is inherently thread-safe and can be used safely across multiple threads.

Character constants and string constants *

  1. Form: A character constant is a single character caused by a single quotation mark. A string constant is several characters caused by a double quotation mark
  2. A string constant represents an address value (where the string is stored in memory).
  3. Memory size Character constant two bytes String constant several bytes (at least one character end flag)

What is a string constant pool? *

String constant pool is located in the heap memory, specially used to store the string constants, can improve the utilization rate of memory, avoid open up more space to store the same piece of string, the JVM will first check when creating a string string constant pool, if the string already exists in the pool, it returns its reference, if not, the instantiation of a string in the pool, And returns its reference.

What are the common methods of the String class? * *

You may not be asked this question in an interview, but you may need to memorize it for an interview or a written test.

  • length(): Returns the length of a string
  • charAt(): Returns the character at the specified index
  • substring(): Intercepts a string
  • trim(): Removes whitespace at both ends of the string
  • split(): Split string, returns an array of split strings.
  • replace(): String replacement.
  • indexOf(): Returns the index of the specified character.
  • toLowerCase(): Converts the string to lowercase.
  • toUpperCase(): Converts the string to uppercase characters.

What’s the difference between a String and a StringBuffer or a StringBuilder? * * *

1. The variability

Strings are immutable, StringBuilder and StringBuffer are mutable

2. Thread safety

Strings are thread-safe because they are immutable. StringBuffer places synchronization locks on methods or on invoked methods, so it is thread-safe. StringBuilder does not lock methods synchronously-so it is not thread-safe.

3. The performance

StringBuilder > StringBuffer > String

For easy memorization, the summary is as follows

If the variable Is it safe performance
String immutable security low
StringBuilder variable unsafe high
StringBuffer variable security higher

Whether the switch works on byte, whether it works on long, and whether it works on String *

Switch applies to char byte short Ints and their corresponding wrapper types. Switch does not apply to Long double float Boolean and their wrapper types. Enumerations are available after JDK1.5 and strings are available after JDK1.7.

What coding scheme does the Java language use? What are the characteristics? *

The Java language uses the Unicode coding standard, which specifies a unique value for each character, so it can be used safely in any language, platform, and program.

Access modifier * *

There are four types of permission access controllers in the Java programming language that control the visibility of members in a class. There are two types of classes: public and default. There are four methods and variables: public, default, protected, and private.

  • Public: visible to all classes. Use objects: classes, interfaces, variables, methods

  • Protected: Visible to classes and all subclasses within the same package. Use objects: variables, methods. Note: You cannot decorate classes (external classes).

  • Default: visible in the same package without any modifiers. Use objects: classes, interfaces, variables, methods.

  • Private: visible within the same class. Use objects: variables, methods. Note: You cannot decorate classes (external classes)

    The modifier The current class With the package Subclass (same package) Other packages
    public Y Y Y Y
    protected Y Y Y N
    default Y Y Y N
    private Y N N N

The operator *

  • && and &

    The final result is true when both conditions are true. The final result is true when both conditions are true. The difference is that if the first condition is false, the second condition is not evaluated, and the final result is false, whereas the ampersand is evaluated for all conditions.

  • | | and |

    | | | and presentation logic, or have in common is that as long as the two judgment conditions established one of the final result is true, the difference is | | as long as meet the first condition, the back is no longer the condition of judgment, and to judge of the condition of all |.

The keyword

Static keyword * * *

The main use of the static keyword is to make it easy to call methods and variables when no object is created and to optimize program performance

1. Static variables

Variables decorated static are called static variables, also known as class variables, and can be accessed directly by the class name. Static variables are shared by all objects and have only one copy in memory that is initialized only when the class is first loaded, whereas non-static variables are initialized when the object is created and have multiple copies that do not affect each other.

2. Static method

Static method does not depend on any object can be accessed, in the static method cannot access non-static member of the class variables and non-static member method, because the static method/variables are all must depend on the specific objects can be invoked, but in a static method is a method to access static members/variables.

public class Main {
    public static String s1 = "s1";// Static variables
    String s2  = "s2";
    public void fun1(a){
        System.out.println(s1);
        System.out.println(s2);
    }
    
    public static void fun2(a){
        System.out.println(s1);
        System.out.println(s2);Static methods cannot call non-static variables}}Copy the code

3. Static code blocks

The main purpose of a static code block is to optimize the performance of a program, because it is only loaded once at class load, and many times it will place initialization operations that only need to be done once in a static code block. If a program has more than one static block, each static block is executed in the order in which the class is first loaded.

public class Main {
    static {
        System.out.println("hello,word");
    }
    public static void main(String[] args) {
        Main m = newMain(); }}Copy the code

4. Can static member variables be accessed through this? (can)

This represents the current object and can access static variables, whereas static methods cannot access non-static variables and cannot use this references.

5. Initialization sequence

Static variables and static statement blocks take precedence over instance variables and normal statement blocks, and the order in which they are initialized depends on the order in which they are placed in the code. If inheritance exists, the initialization order is static variables and static code blocks in the parent class — static variables and static code blocks in the child class — instance variables and normal code blocks in the parent class — constructor of the parent class — instance variables and normal code blocks in the child class — constructor of the child class

The final keyword * * *

The final keyword is used to modify classes, variables, and methods.

  1. Class:finalModified classes may not be inherited
  2. Methods:finalThe decorated method cannot be overridden
  3. Variables:finalThe modified variable is a basic type, and its value cannot be changed; The variable to be modified is a reference type. The variable cannot refer to other objects, but the object referenced by the variable can be changed.
public class Main {
    int a = 1;
    public static void main(String[] args) {
        final int b = 1;
        b = 2;/ / an error
        final Main m = new Main();
        m.a = 2;// Without error, you can change the object to which the reference type variable points}}Copy the code

Final finally Finalize distinguishes * * *

  • finalUsed to modify classes, variables, and methods
  • finallyIn generaltry-catchIn a code block, we will usually have to execute code methods when handling exceptionsfinallyIn a code block, the code block is executed regardless of whether an exception occurs, and is generally used to store some code to close the resource.
  • finalizeIs one of theObjectClass, which is normally called by the garbage collector when we callSystem.gc() Method is called by the garbage collectorfinalize()Garbage collection, but the Java language specification does not guarantee thatinalizeMethods are executed in a timely manner, and there is no guarantee that they will be executed.

This keyword * *

Focus on mastering the first three

1. The this keyword can be used to refer to instance variables of the current class. This is used to form members with the same name.

public Person(String name, int age) {
    this.name = name;
    this.age = age;
}
Copy the code

2. The this keyword can be used to call the current class method.

public class Main {
    public void fun1(a){
        System.out.println("hello,word");
    }
    public void fun2(a){
        this.fun1();/ / this can be omitted
    }

    public static void main(String[] args) {
        Main m = newMain(); m.fun2(); }}Copy the code

3. This () can be used to call the constructor of the current class. (Note: this() must be on the first line of the constructor, otherwise it will not compile.)

class Person{
    private String name;
    private int age;
    
    public Person(a) {}public Person(String name) {
        this.name = name;
    }
    public Person(String name, int age) {
        this(name);
        this.age = age; }}Copy the code

4. The this keyword can be passed as an argument in the calling method.

5. The this keyword can be passed as an argument in a constructor call.

6. The this keyword can be used to return an instance of the current class from a method. super

The super keyword * *

1. Super can be used to refer to instance variables of the immediate parent class. Similar to this, this is used to distinguish the same fields in a parent class from a subclass

2. Super can be used to call the direct superclass constructor. (Note: super() must be placed on the first line of the constructor, otherwise it will not compile.)

3. Super can be used to call direct superclass methods.

public class Main {
    public static void main(String[] args) {
        Child child = new Child("Father"."Child"); child.test(); }}class Father{
    protected String name;

    public Father(String name) {
        this.name = name;
    }

    public void Say(a){
        System.out.println("hello,child"); }}class Child extends Father{
    private String name;

    public Child(String name1, String name2) {
        super(name1);      // Call the direct parent constructor
        this.name = name2;
    }

    public void test(a){
        System.out.println(this.name);
        System.out.println(super.name);  // Reference the instance variable of the immediate parent class
        super.Say();      // Call the direct parent method}}Copy the code

The difference between this and super * *

  • Similarities:

    1. super()andthis()Both must be called on the first line of the constructor, otherwise it is an error
    2. this()andsuper()Both refer to objects, therefore, can not be instaticUsed in the environment.
  • Difference:

    1. super()Mainly calls to the superclass constructor,this()Is a call to an overloaded constructor
    2. super()It is used mainly in constructors of subclasses that inherit from the parent class, but in different classes.this()Mainly used in different constructors of the same class

Break,continue,return * *

  • breakCompletes the current loop body
  • continueEnd the loop and enter the next loop
  • returnEnd current method

The difference between object-oriented and procedural * *

  • Process oriented

    Advantages: Higher performance than object-oriented, because class invocation needs to be instantiated, high overhead, more resource consumption.

    Disadvantages: No object-oriented easy maintenance, easy reuse, easy to expand

  • object-oriented

    Advantages: easy to maintain, easy to reuse, easy to expand, because of the characteristics of object-oriented encapsulation, inheritance, polymorphism, can design a low coupling system, make the system more flexible, more easy to maintain

    Disadvantages: Lower performance than process-oriented

Three major object-oriented features (encapsulation, inheritance, polymorphism) * * *

  • encapsulation

    Encapsulation hides the attributes and implementation details of an object, exposes the interface only, and controls the level of access to read and modify attributes in the program.

  • inheritance

    Inheritance is when a subclass inherits the characteristics and behavior of its parent class, making its object (instance) have the instance fields and methods of its parent class, or a subclass inherits methods from its parent class, making it have the same behavior as its parent class.

  • Polymorphism (important)

    Polymorphism is the ability to have many different manifestations or forms of the same behavior. This sentence is not very good understanding, we can see this explanation, in the Java language, polymorphism is refers to the procedures defined in the reference variable is pointing to the specific type and referenced by the variable from method calls are not sure when programming, but during the program is run to determine, that is, a reference variable STLL can point to which class instance objects, The method call issued by the reference variable must be determined during program execution in which class the method is implemented.

    There are three necessary conditions for implementing polymorphism in Java: inheritance, rewriting, and upward transition. Inheritance and overwriting are well understood, but upcasting is when you need to assign a reference to a subclass to a superclass object in a polymorphism.

    public class Main {
        public static void main(String[] args) {
              Person person = new Student(); // Upward transitionperson.run(); }}class Person {
        public void run(a) {
            System.out.println("Person"); }}class Student extends Person {   / / inheritance
        @Override 
        public void run(a) {         / / overloaded
            System.out.println("Student"); }}Copy the code

    The run result is

    Student
    Copy the code

What are the five basic principles of object orientation

  • Single-responsibility Principle

    ** A class, preferably one that does only one thing, only one that causes it to change. The principle of single responsibility can be regarded as an extension of the object-oriented principle of low coupling and high cohesion. Responsibility is defined as the cause of change, so as to improve cohesion to reduce the cause of change.

  • The Open-Closed principle

    Software entities should be extensible, not modifiable. That is, open to extension, closed to modification.

  • Liskov-substituion Principle

    ** Subclasses must be able to replace their base classes. ** this idea is reflected in the constraint specification of inheritance mechanism. Only when the subclass can replace the base class, can the system recognize the subclass in the running period, which is the basis for ensuring inheritance reuse. In the specific behavior of the parent class and the subclass, the relationship and characteristics in the inheritance hierarchy must be strictly grasped, and the behavior of the program will not change if the base class is replaced by the subclass. At the same time, this constraint is reversed is not true, the subclass can replace the base class, but the base class does not necessarily replace the subclass.

  • Dependecy-inversion Principle

    ** relies on abstraction. ** Specifically, high-level modules do not depend on low-level modules, and both depend on abstraction; Abstract does not depend on concrete, concrete depends on abstraction.

  • Interface Segregation Principle

    Use multiple small specialized interfaces rather than one large overall interface.

Abstract classes versus interfaces * * *

Abstract class and Interface are two mechanisms in the Java language that support abstract class definitions. Abstract class: Used to capture the common features of subclasses. Interface: Collection of abstract methods.

Similarities:

  • Neither interfaces nor abstract classes can be instantiated
  • Both contain abstract methods that must be overridden by their subclasses

Difference:

type An abstract class interface
define abstract class Interface
implementation Extends (needs to provide implementations of all declared methods in an abstract class) Implements (needs to provide implementations of all declared methods in the interface)
inheritance Abstract classes can inherit a class and implement multiple interfaces; Subclasses can inherit only one abstract class Interfaces can only inherit interfaces (one or more); Subclasses can implement multiple interfaces
Access modifier Abstract methods can have public, protected, and default modifiers The default modifier for interface methods is public. You may not use other modifiers
The constructor Abstract classes can have constructors Interfaces cannot have constructors
Field declarations The field declaration of an abstract class can be arbitrary Interface fields are static and final by default

The role of defining a constructor in Java that does nothing and takes no arguments *

Java programs have inheritance. When a constructor of a subclass is executed, if the superclass-specific constructor is not called with super(), the “no-arguments constructor” of the superclass will be called. If the parent class defines only constructors with arguments, and the subclass’s constructor does not call the parent class’s particular constructor with super, an error occurs.

The subclass constructor with no arguments is called before the subclass constructor is called, with the purpose of *

Help subclasses do initialization work.

What does a class constructor do? If a class does not declare a constructor, does the modifier execute correctly? Why is that? *

The main function is to complete the initialization of the class object. Yes. Because a class will have a default constructor that takes no arguments even if it does not declare a constructor.

What are the properties of constructors? * *

  • The method name is the same as the class name
  • You do not define return value types
  • Can not writeretrunstatements
  • Constructors can be overloaded

Variable * *

  • Class variable: a variable that is independent of a method and is modified static.

  • Instance variable: A variable independent of a method, but without the static modifier.

  • Local variables: variables in a method of a class.

  • Member variables: Member variables are also called global variables. They can be classified into class variables and instance variables.

    Class variables The instance variables A local variable
    Define the location In class, out of method In class, out of method In the method
    The initial value There are default initial values There are default initial values No default initial value
    Storage location Methods area The heap The stack
    The life cycle When classes are loaded and unloaded When an instance is created and destroyed When a method is called and ends the call

Inner class * *

Inner classes include four types: member inner classes, local inner classes, anonymous inner classes, and static inner classes

  • Member inner class

    1. A member inner class is defined as being inside another class. The member inner class has unconditional access to all member attributes and methods of the external class (private and static members).

    class Outer{
        private double a = 0;
        public static int b =1;
        public Outer(double a) {
            this.a = a;
        }
    
        class Inner {     / / inner classes
            public void fun(a) { System.out.println(a); System.out.println(b); }}}Copy the code

    2. When an inner class has a member variable or method with the same name as the outer class, the default is to access a member of the inner class. If you want to access a member of an external class with the same name, you need to access it in the form of: external class.this. Member variables

    3. If you want to access a member of an inner class in an external class, you must first create an object of the inner class and then access it through a reference to the object.

    4. The inner class of a member is dependent on the outer class. If you want to create an object of the inner class of a member, the premise is that there must be an object of the outer class. The general way to create a member inner class object is as follows:

    class Outter{
        private double a = 0;
        public static int b =1;
        public Outter(a){}
        public Outter(double a) {
            this.a = a;
            Inner inner = new Inner();
            inner.fun();     // Call the inner class method
        }
    
    
        class Inner {     / / inner classes
            int b = 2;
            public void fun(a) {
                System.out.println(a);
                System.out.println(b);            // Access b of the inner class
                System.out.println(Outter.this.b);// Access b of the external class}}}public class Main{
        public static void main(String[] args) {
            Outter outter = new Outter();
            Outter.Inner inner = outter.new Inner(a); // Create an object for the inner class}}Copy the code
  • Local inner class

    A local inner class is a class defined in a method or scope. It differs from a member inner class in that access to a local inner class is limited to the method or scope. A local class defined in an instance method can access all variables and methods of the external class. A local class defined in a static method can access only static variables and methods of the external class.

    class Outter {
    
        private int outter_a = 1;
        private static int static_b = 2;
    
        public void test1(a){
            int inner_c =3;
            class Inner {
                private void fun(a){
                    System.out.println(outter_a);
                    System.out.println(static_b);
                    System.out.println(inner_c);
                }
            }
            Inner  inner = new Inner(); // Create a local inner class
            inner.fun();
        }
        public static void test2(a){
            int inner_d =3;
            class Inner {
                private void fun(a){
                     System.out.println(outter_a); // a compilation error. A local class defined in a static method cannot access instance variables of an external class
                    System.out.println(static_b);
                    System.out.println(inner_d);
                }
            }
            Inner  inner = newInner(); inner.fun(); }}Copy the code
  • Anonymous inner class

    Anonymous inner classes are only inner classes that do not have names and are often used in daily development. A prerequisite for using anonymous inner classes is that you must inherit a parent class or implement an interface.

    interface Person {
        public void fun(a);
    }
    class Demo {
        public static void main(String[] args) {
             new Person() {
                public void fun(a) {
                    System.out.println("hello,word"); } }.fun(); }}Copy the code
  • Static inner class

    A static inner class is a class defined in another class with the keyword static in front of it. A static inner class does not need to depend on an external class, and it cannot use non-static member variables or methods of the external class. This makes sense because it is possible to create an object of a static inner class without an object of the external class. Allowing access to a non-static member of the external class would cause a contradiction. Because non-static members of an external class must be attached to a concrete object.

    class Outter {
        int a = 1;
        static int b = 2;
        public Outter(a) {}static class Inner {
            public Inner(a) {
                System.out.println(a);Static inner class cannot access non-static variablesSystem.out.println(b); }}}public class Main{
        public static void main(String[] args) {
            Outter.Inner inner = newOutter.Inner(); }}Copy the code
  • Advantages of inner classes:

    1. The inner class is not seen by other classes in the same package and has good encapsulation.
    2. Anonymous inner classes make it easy to define callbacks.
    3. Each inner class can independently inherit an implementation of an interface, so it doesn’t matter whether the outer class already inherits an implementation.
    4. Inner classes effectively implement “multiple inheritance”, optimizing the pitfalls of Java single inheritance.
  • When a local inner class or an anonymous inner class accesses a local variable, why must the variable be final?

    public class Main {
        public static void main(String[] args)  {}public void fun(final int b) {
            final int a = 10;
            new Thread(){
                public void run(a) { System.out.println(a); System.out.println(b); }; }.start(); }}Copy the code

    For variables can be understood from the perspective of life cycle, a stored directly on the stack for local variables, when the method is complete, the final local variables will be destroyed, and local inner classes of the local variable references still exists, if there is no final modified local inner classes should call local variables, inconsistent error will cause life cycle.

    In the case of variable B, we initialize the assignment of variable B in fun as an argument to a copy (of variable B) in the anonymous inner class. The variable b accessed in the run method is not a local variable B in the test method at all, but a copy value, so there is no problem with inconsistent life cycle. However, if the value of variable B is changed in the run method, the data will be inconsistent, so we need to add final modification.

Overwrite and reload * * *

The difference between overloading and overwriting

  • Overloading: Occurs in the same class with the same method name and different parameter lists (different parameter types, numbers, and orders), regardless of method return values and access modifiers, that is, overloaded methods cannot be distinguished by their return types.
  • Overwrite: in a parent class, the method name and parameter list must be the same, the return value must be less than or equal to the parent class, the exception thrown must be less than or equal to the parent class, and the access modifier must be greater than or equal to the parent class (Richter substitution rule); If the parent method access modifier isprivateIt’s not overridden in a subclass.

Whether the constructor can be overridden

Constructors can be overridden and cannot be overridden

Can overloaded methods be differentiated by return type? Why is that?

No, because you can’t specify type information when calling, and the compiler doesn’t know which function you want to call.

== equals * * *

  • = =

    For basic data types, == compares values; For reference data types, == compares memory addresses.

  • eauals

    Equals works like == for classes that do not override equals; For classes that override equals, equals compares values.

HashCode and equals (why should hashCode be overridden after overwriting equals) * * *

  • equals

    Take a look at the equals method overridden in the String class.

        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;
        }
    Copy the code

    From the source can be seen:

    1. equalsMethod first compares the memory address, and returns the same memory addresstrue; If the memory address is different, the object type is comparedfalse; The type is the same, and then compare whether the value is the same; Returns the same valuetrue, returns different valuesfalse. So to sum up,equalsWill be moreMemory address, object type, and value, memory address is the same,equalsMust be returnedtrue; Object type and value are the same,equalsMethod must returntrue.
    2. If I didn’t rewrite itequalsMethod, thenequalsand= =Is used to compare the address values of objects.
  • hashCode

    The hashCode method returns the hashCode of the object. The return value is a hashCode of type int. The purpose of the hash code is to determine the index position of the object in the hash table.

    There are some conventions for hashCode:

    1. If two objects are equal, thenhashCodeIt must be the same.
    2. Two objects have the samehashCodeValues, they don’t have to be equal.
    3. hashCode()Method defaults to produce unique values for objects on the heap, if not overriddenhashCode()Method for two objects of the classhashCodeThe values must be different
  • Why does the hashCode method have to be overridden after overriding equals

    1. By definition, two objects are equal,hashCodeMaybe the values are the same, so rewriteequalsMethods after,hashCodeMethods must also be rewritten (this is definitely not what the interviewer wants to hear)
    2. hashCodePlays a critical role in collections that have hash mechanisms, for exampleHashMap,HashSetAnd so on. In order toHashSetFor example,HashSetIs characterized by unordered and unique storage of elements in the directionHashSetThe prime minister will calculate the object when adding it toHashCodeValue to determine the location where the object is stored. If there are no other objects in the location, the object is directly added to the location. If the storage location has stores other objects (newly added objects and objects at the storage location)HashCodeSame value), callequalsMethod to determine whether two objects are the same. If they are, the object fails to be added. If they are not, the object is rehashed to another location. So rewriteequalsMethods after,hashCodeMethod, if not overridden, will result in all objectsHashCodeThe values are all different, they can be added successfully, soHashSetThere are a lot of repeating elements in,HashMapIn the same way (becauseHashSetThe bottom is throughHashMapImplemented), there will be a lot of the sameKey(HashMapIn thekeyIs unique, but differentkeyIt could correspond to the same thingvalue). So rewriteequalsMethods after,hashCodeMethods must also be rewritten. Because of both objects at the same timehashCodeIf the values are different, they must not be equal, so evaluate the values of the objects firsthashCodeValue can judge whether two objects are equal to some extent, which improves the efficiency of collection. To sum up, there are two points:The first,HashSetI’m not going to rewrite ithashCodeMethods can cause their functionality to fail; Second, it can improve the efficiency of collection.

Is it value passing or reference passing in Java, or both? * *

This is a very confusing and difficult problem to explain, first of all the conclusion, Java only has value passing

So let’s look at some code like this

public class Main{
    public static void main(String[] args) {
        int a = 1;
        printValue(a);
        System.out.println("a:" + a);
    }
    public static void printValue(int b){
        b = 2;
        System.out.println("b:"+ b); }}Copy the code

The output

b:2
a:1
Copy the code

You can see that you pass the value of a into the printValue method and change its value to 2. But after the method call, the value of A remains 1, unchanged, so the value is passed in this case.

Look at this code again

public class Main{
    public static void main(String[] args) {
        Preson p = new Preson();
        p.name = "zhangsan";
        printValue(p);
        System.out.println("p.name: " + p.name);
    }
    public static void printValue(Preson q){
        q.name = "lisi";
        System.out.println("q.name: "+ q.name); }}class Preson{
    public String name;
}
Copy the code

The output

q.name: lisi
p.name: lisi
Copy the code

After passing p to printValue, the method call ends and p’s name property is changed! Therefore, it is concluded that if the parameter is of basic type, it is passed by value, and if the parameter is of reference type, it is passed by reference. That’s not true. Now what’s the key to value pass or value pass? What’s the definition

  • Value passing: When a function is called, a copy of the actual parameter is passed to the function, so that the actual parameter is not affected if the parameter is modified.
  • Pass by reference: When a function is called, the address of the actual parameter is directly passed to the function. Therefore, the modification of the parameter in the function will affect the actual parameter.

It is clear from the definition that the difference between value passing and reference passing is mainly based on whether the method is passing a copy of the actual parameter or the address of the actual parameter. In the second example, we pass a copy of a reference to the same object as the original reference, so the properties of the object modified by the copy reference must also have been modified by the original reference. In other words, the printValue method changes the properties of the object to which the copy reference points, not the reference itself. If you change the reference itself, the original reference will not be affected. Look at the following example

public class Main{
    public static void main(String[] args) {
        Preson p = new Preson();
        p.name = "zhangsan";
        printValue(p);
        System.out.println("p.name: " + p.name);
    }
    public static void printValue(Preson q){
        q = new Preson();
        q.name = "lisi";
        System.out.println("q.name: "+ q.name); }}class Preson{
    public String name;
}
Copy the code

The output

q.name: lisi
p.name: zhangsan
Copy the code

You can see that when you pass p to printValue, the property name of p does not change after the call to printValue. This is because in printValue, you do not change the object to which the copy reference q refers, but you change the copy reference q itself. The copy reference q points to another object and changes its properties, so that the object to which the original reference P refers is unaffected. So proving that only value passing exists in Java.

IO stream *

Java IO streams can be divided into input streams and output streams. According to the operation unit, it can be divided into byte stream and character stream. Flows are divided into node flows and processing flows according to their roles.

The Java I0 stream’s 40-plus classes are derived from four abstract base classes.

  • InputStream: byte InputStream
  • Reader: character input stream
  • OutputStream: byte OutputStream
  • Writer: character output stream

What’s the difference between BIO,NIO and AIO? * *

  • Blocking I/O (BIO) : The server implementation mode is one connection one thread, that is, when the client has a connection request, the server needs to start a thread to process. If the connection does not do anything, it will cause unnecessary thread overhead, which can be improved through the thread pool mechanism. The BIO mode is suitable for architectures with a small and fixed number of connections. This mode requires high server-side resources, and the concurrency is limited to the application. Prior to JDK1.4, it was the only IO

  • NIO (New I/O) : The server implementation mode is one request one thread, that is, the connection request sent by the client is registered with the multiplexer, and the multiplexer polls the connection to have I/O requests until a thread is started to process. NIO mode is suitable for the architecture with large number of connections and relatively short connections (light operation), such as chat server, concurrency is limited to the application, the programming is relatively complex, jdK1,4 began to support

  • Asynchronous I/O (AIO) : the server implements a valid request for one thread, and the client’s I/O request is completed by the operating system and then notified to the server to use its starting thread to process it. AIO is suitable for architectures with large number of connections and long connections (heavy operations), such as album server, which fully invokes OS to participate in concurrent operations. Programming is complicated and is supported in JDK1.7.

    These concepts may seem boring, but you can understand them from the classic boiling water example

    BIO: Go to the kitchen, start boiling water NIO, and sit in front of the kettle and wait for the water to boil.

    NIO: Go to the kitchen, turn on the AIO and boil the water, but instead of sitting in front of the kettle all the time, we do something else, and then go to the kitchen every few minutes to check if the water is boiling.

    AIO: We go into the kitchen and we boil the water, and instead of sitting in front of the kettle and waiting, we put a switch on the kettle and it tells me when it’s boiling.

Reflection * * *

The JAVA reflection mechanism allows you to know all the properties and methods of any class in the running state. For any object, you can call any of its methods and properties; This ability to dynamically retrieve information and invoke methods on objects is called the Reflection mechanism of the Java language.

Java gets Class objects in three ways

class Person {
    public String name = "zhangsan";
    public Person(a) {}}Copy the code
public class Main{
    public static void main(String[] args) throws ClassNotFoundException {
	1 / / way
     Person p1 = new Person();
     Class c1 = p1.getClass();
     2 / / way
    Class c2 = Person.class;
    Method 3 May throw a ClassNotFoundException
    Class c3 = Class.forName("com.company"); }}Copy the code

Because there is only one Class instance of a Class in the JVM, equals comparisons of C1, c2, and c3 all return true.

Advantages and disadvantages of reflection:

  • Advantages: Runtime type judgment, dynamic loading classes, improve code flexibility.
  • Cons: Performance is much slower than straight Java code.

Reflection application scenarios:

  1. Many frameworks in Java use reflection, for exampleSpringXML configuration mode, etc
  2. The dynamic proxy design pattern also uses reflection

JAVA exception * * *

Exceptions are mainly divided into Error and Exception

  • Error:ErrorClass, and instances of its subclasses, represent errors in the JVM itself. Errors cannot be handled by programmers in code.
  • EXception:ExceptionAnd its subclasses, which represent all sorts of unexpected events sent while the program is running. Can be used by the Java exception handling mechanism, is the core of exception handling.

Abnormal block diagram

In addition to the above classification, exceptions can also be classified as non-check exceptions and check exceptions

  • Unexamined anomaly(Unckecked Exception) : ** This class includes runtime exceptions (RuntimeException and subclasses) and errors. ** The compiler does not check and does not require exceptions that must be handled, that is, when such exceptions occur in the program, even if we do nottry-catchIt is captured and not usedthrowsThrow this exception, and the compilation will pass. Because the reason such exceptions occur is probably because the code is written incorrectly.
  • Check the abnormalChecked Exception: ** ExceptError andRuntimeExceptionOther exceptions. ** This is an exception that the compiler is required to handle. Such exceptions are usually caused by the environment in which the program is running. These exceptions must be handled because programs can be run in all kinds of unknown environments, and the programmer has no way of interfering with how the user uses the program he wrote.

Try {}catch(){}finally{} and return. Try {}catch(){}finally{} Let’s look at the code and guess.

public class Main{
    public static void main(String[] args) {
        int a = test1();
        System.out.println(a);
        int b = test2();
        System.out.println(b);
        int c = test3();
        System.out.println(c);
        int d = test4();
        System.out.println(d);
        int e = test5();
        System.out.println(e);
    }
    public static int test1(a){
        int a = 1;
        try{
            a = 2;
            return a;
        }catch(Exception e){
            System.out.println("hello,test1");
            a = 3;
        }finally{
            a = 4;
        }
        return a;
    }
    2 / / output
    
    
    public static int test2(a){
        int a = 1;
        try{
            a = 2;
            return a;
        }catch(Exception e){
            System.out.println("hello,test2");
            a = 3;
            return a;
        }finally{
            a = 4; }}2 / / output
    
    
    public static int test3(a){
        int a = 1;
        try{
            a = 2/0;
            return a;
        }catch(Exception e){
            System.out.println("hello,test3");
            a = 3;
        }finally{
            a = 4;
        }
        return a;
    }
    / / output hello, test3
    / / 4
    
    
    public static int test4(a){
        int a = 1;
        try{
            a = 2/0;
            return a;
        }catch(Exception e){
            System.out.println("hello,test4");
            a = 3;
            return a;
        }finally{
            a = 4; }}/ / output hello, test4
    / / 3
    
    public static int test5(a){
        int a = 1;
        try{
            a = 2/0;
            return a;
        }catch(Exception e){
            a = 3;
            return a;
        }finally{
            a = 4;
            returna; }}/ / output 4
}
Copy the code

If there is no careful study, should be a lot of guess wrong, sum up the rule below.

  1. The first three examples show iftry{}There is no exception in the code incatch(){}Code in a code block does not execute. So iftry{}andcatch(){}All containreturn, no exception is executedtry{}In thereturnException execution existscatch(){}thereturn.
  2. In any case, even iftry{}orcatch(){}containsreturn.finally{}The code must be executed, so whytest1,test2,test3It’s not going to be 4 because althoughfinallyIs in thereturnThe following expression is executed after the operation, but instead of returning the value after the operation, the value is stored regardlessfinallyAny changes to this value do not change the returned value, but still return the saved value. That is, the return value of the method is infinallyWe determined it before we did the calculation.
  3. ifreturnThe data is referenced to the data type, while infinallyChanges to the value of the attribute of the reference data type,tryIn thereturnThe statement returns the value offinallyIs the changed value of this property. Look at the Java value passing problem mentioned above.
  4. iffinally{}containsreturn, the program will exit in advance and not be executedtry{}orcatch(){}In thereturn. sotest5The value returned is 4.

Try {}catch(){}finally{}

  1. To perform firsttry, includingreturnThe following expression;
  2. If an exception occurs, run the commandcatch, includingreturnThe following expression is skipped without exceptioncatchStatements;
  3. Then performfinallyIffinallyThere is areturnStatement, executereturnStatement, program end;
  4. finally{}There is noreturn, no exception is executedtryIn thereturnIf there is an exception, the command is executedcatchIn thereturn. The first two steps are executedreturnI’m just determining the value that’s returned, the program is not finished,finally{}After execution, the last two steps will be determinedreturnReturns the return value of.

JAVA annotations * *

There are not many interview questions, but they are often used when using framework development, but there are too many things, so here is a brief introduction to the concepts.

An Annotation can be thought of as a markup in Java that adds additional explanatory information to any program element in Java, such as classes, members, methods, parameters, etc., without changing program semantics. Annotations can be divided into three categories: basic annotations, meta-annotations, and custom annotations

  • Standard annotations

    1. Deprecated: This annotation indicates that an element (class, method, member variable, etc.) in a program is no longer in use and will be warned by the compiler if it is Deprecated.
    2. @SuppressWarnings(value= “”) : Suppresses all possible warnings.
    3. Override: Indicates that a subclass method overrides a parent class method, protecting the proper use of the Override method
  • Meta-annotations (also known as metadata annotations, meta-annotations are annotations that annotate annotations. Meta-annotations are more like a specification of annotations, used to define the behavior of annotations. For example, explain the lifetime of annotations, the scope of annotations, etc.)

    1. @target (value= “”) : This annotation is used to limit the scope of the annotation, that is, which program elements the annotation can be used for.
    2. @Retention(value= “”) : Indicates the Retention period of annotations
    3. @Documnent: Describes that a annotation specifying that it is modified can be extracted into the document by the Javadoc.exe tool. All classes annotated with this annotation include the annotation when generating the API document.
    4. Inherited: used to refer to the parent class that uses this annotation. The child classes inherit this annotation automatically.
    5. Repeatable: meta annotation new in java1.8 that needs to be marked if the same type of annotation is needed for program elements.
  • Custom annotations: use @interface to declare annotations.

JAVA generics * * *

Java generics are a new feature introduced in JDK 5. Generics provide compile-time type-safety checks that allow programmers to detect illegal types at compile time. The nature of generics is parameterized typing, which means that the data type being operated on is specified as a parameter.

  • Generic erasure (this is a common interview question when examining generics)

    Java generics are basically implemented at the compiler level. The generated bytecode does not contain the type information in the generics. When the generics are used, the type parameters will be removed when the compiler compiles, and this process is called type erasing. Look at the following code

    public class Main{
        public static void main(String[] args) {
            ArrayList<Integer> arrayList1 = new ArrayList<>();
            ArrayList<String> arrayList2 = newArrayList<>(); System.out.println(arrayList1.getClass() == arrayList2.getClass()); }}Copy the code

    The output

    true
    Copy the code

    As you can see, ArrayList

    and ArrayList

    have the same primitive type, and both become lists when they are encoded into bytecode files. The JVM sees only the List, but no generic information. Look at the code below

    public class Main{
        public static void main(String[] args) throws Exception {
            ArrayList<Integer> arrayList = new ArrayList<>();
            arrayList.add(1);
            arrayList.getClass().getMethod("add", Object.class).invoke(arrayList, "a");
            System.out.println(arrayList.get(0));
            System.out.println(arrayList.get(1)); }}Copy the code

    The output

    1
    a
    Copy the code

    You can see that with reflection add, ArrayList

    can actually store strings, because reflection is the add method that is called at run time, and at run time the generic information is erased.

  • Given that type erasure exists, how does Java guarantee that adding strings to ArrayList

    will report an error?

    The Java compiler checks the code for generic types, erases them, and then compiles them.

JAVA serialization * *

  • Serialization: Writes an object to an IO stream

  • Deserialization: Recover objects from AN IO stream

  • Serialization meaning: To convert Java objects into sequences of bytes that are easier to transfer over the network or store on disk and can be deserialized back to the original object if needed.

  • Implementation method:

    1. Implement the Serializable interface
    2. Implement the Externalizable interface
  • Serialization considerations:

    1. Object class names and instance variables are serialized; Methods, class variables,transientNone of the instance variables are serialized.
    2. A variable that is not serialized can be usedtransientModification.
    3. The reference type member variable of the serialized object must also be serializable; otherwise, an error is reported.
    4. Deserialization must have a serialized objectclassFile.

Deep copy and shallow copy * * *

  • Deep copy: Passes values to the base data type, creates a new object for the reference data type, and copies its contents. Two references point to two objects, but the objects have the same contents.

  • Shallow copy: Passes values to the primitive data type and copies a reference to the object referenced in the original reference. That is, the copied reference points to the same object as the original reference.

    See the following figure for specific differences

  • Deep copy implementation

    1. Overload Clone method

       public class Main{
          public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, CloneNotSupportedException {
              Address s = new Address("Tianjin");
              Person p = new Person("Zhang".23, s);
              System.out.println("Address before cloning:" + p.getAddress().getName());
              Person cloneP = (Person) p.clone();
              cloneP.getAddress().setName("Beijing");
              System.out.println(Cloned address:+ cloneP.getAddress().getName()); }}class Address implements Cloneable {
          private String city;
          public Address(String name){
              this.city = name;
      }
          @Override
          protected Object clone(a) throws CloneNotSupportedException {
                  return super.clone();
          }
          public String getName(a) {
              return city;
      
          }
          public void setName(String name) {
              this.city = name; }}class Person implements Cloneable{
          private String name;
          private int age;
          private Address address;
          public Person(String name, int age, Address address){
              this.name = name;
              this.age = age;
              this.address = address;
      
          }
          @Override
          public Object clone(a) throws CloneNotSupportedException {
                Person  person = (Person) super.clone();
                person.address = (Address)address.clone();
              return person;
          }
          public String getName(a) {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public int getAge(a) {
              return age;
          }
          public void setAge(int age) {
              this.age = age;
          }
          public Address getAddress(a) {
              return address;
          }
          public void setAddress(Address address) {
              this.address = address; }}Copy the code

      The output

      Address before cloning: Tianjin Address after cloning: BeijingCopy the code

      Clone () is a shallow clone, and the Address object will need to be reassigned by the address.clone() call. Because the address type is a reference type.

    2. serialization

      public class Main{
          public static void main(String[] args) throws IOException, ClassNotFoundException {
              Address s = new Address("Tianjin");
              Person p = new Person("Zhang".23, s);
              System.out.println("Address before cloning:" + p.getAddress().getName());
              Person cloneP = (Person) p.deepClone();
              cloneP.getAddress().setName("Beijing");
              System.out.println(Cloned address:+ cloneP.getAddress().getName()); }}class Address implements Serializable{
          private String city;
          public Address(String name){
              this.city = name;
          }
      
          public String getName(a) {
              return city;
      
          }
          public void setName(String name) {
              this.city = name; }}class Person implements Serializable{
          private String name;
          private int age;
          private Address address;
          public Person(String name, int age, Address address){
              this.name = name;
              this.age = age;
              this.address = address;
      
          }
      
          public Object deepClone(a) throws IOException, ClassNotFoundException {        
              ByteArrayOutputStream bos = new ByteArrayOutputStream();
              ObjectOutputStream oos = new ObjectOutputStream(bos);
              oos.writeObject(this);        
              ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
              ObjectInputStream ois = new ObjectInputStream(bis);
              return ois.readObject();
          }
      
          public String getName(a) {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public int getAge(a) {
              return age;
          }
          public void setAge(int age) {
              this.age = age;
          }
          public Address getAddress(a) {
              return address;
          }
          public void setAddress(Address address) {
              this.address = address; }}Copy the code

      The output

      Address before cloning: Tianjin Address after cloning: BeijingCopy the code

The common Object method * * *

These are all very important, and are often asked in interviews. Understand them in conjunction with other knowledge

  • Object clone(): Creates a new object that is the same as the object’s class
  • boolean equals(Object): Compares whether two objects are equal
  • void finalize()The object garbage collector calls this method when the garbage collector determines that no more references to the object exist
  • Class getClass(): returns the instance class of an object runtime
  • int hashCode(): Returns the hash code value of the object
  • void notify(): Wakes up a thread waiting on the monitor for this object
  • void notifyAll(): Wakes up all threads waiting on the monitor for this object
  • String toString(): Returns a string representation of the object
  • void wait(): used to call this object in another threadnotify()Method ornotifyAll() Method causes the current thread to wait