Java - 常见问题及解答
Q&A
Compile and Execution
- Java Compiling and Running Process | by amirreza lotfi | Javarevisited | Medium
- Compilation and Execution of a Java Program - GeeksforGeeks
- What are the things are checked at compile time by Java? - Quora
Different behaviour in JShell
Question:
- Why when execute
int a;
,the variablea
was initialized to0
rather than compile error?
Answer:
- java - Different behaviour of same statement while executing on JShell - Stack Overflow
- JEP 222: jshell: The Java Shell (Read-Eval-Print Loop) (openjdk.org)
- JEP 222: jshell: The Java Shell (Read-Eval-Print Loop) (openjdk.org)
Memory usage
Objects
Question:
- How many memory usage of objects in java?
Answer:
- Memory usage of objects in Java (javamex.com)
- How to calculate the memory usage of Java objects (javamex.com)
- Memory Usage Estimation in Java | Better Programmer (kiyanpro.com)
Conversion
Primitive Conversion
Question:
- What is conversion between primitive like char, int, float, double…?
Answer:
- Chapter 5. Conversions and Contexts (oracle.com) Widening and Narrowing
Autoboxing and Unboxing
Question:
- What is autoboxing?
Answer:
- Autoboxing and Unboxing (The Java™ Tutorials > Learning the Java Language > Numbers and Strings) (oracle.com)
- Also see the
5.4 Object Wrappers and Autoboxing
ofCore-Java-Volume-I-Fundamentals-12th-Edition-Cay-S.-Horstmann
Question:
- What will happen if i use
==
to compare twoInteger
?
Answer:
- How can I properly compare two Integers in Java? - Stack Overflow
- Chapter 5. Conversions and Contexts (oracle.com)
- Integer (Java Platform SE 8 ) (oracle.com)
- Java gotchas - OWASP
- Java Integer Cache - GeeksforGeeks
- When 1 + 1 = 3 (pedrorijo.com)
- Also see the
5.4 Object Wrappers and Autoboxing
ofCore-Java-Volume-I-Fundamentals-12th-Edition-Cay-S.-Horstmann
- The Geeky Way – Java: Autoboxing and -XX:AutoBoxCacheMax
- Also see the
private static class IntegerCache
in theInteger.java
source code. - Java Integer Cache - Javapapers——The better one
- What is Autoboxing and Unboxing in Java ? Example, Tutorial and Corner cases (javarevisited.blogspot.com)
- Java - Integer Cache - Abel's Blog (chen-huaneng.github.io)
Note:
In the source code Integer.java
, there are a
private static class IntegerCache
to cache the
Integer
in range of -128 and 127. You can modify the range
on command-line option like
java -XX:AutoBoxCacheMax=1000 YOURCLASSNAME
which will
cache Integer
range -128 to 1000 rather than the
default.
How to using -XX:AutoBoxCachMax=<size>
to change
the cache range.
@Source Java’s -XX:+AggressiveOpts: Can it slow you down? (opsian.com)
AutoBoxCacheMax
For those less familiar with Java, AutoBoxing is where the compiler automatically converts between primitive and boxed types. E.g
int
andInteger
. Autoboxing is mostly a code readability feature without which there would need to be a lot more casting when mixing primitives and boxed types.Boxing integers repeatedly can be expensive and since Java’s boxed types are immutable there exists a cache where a configurable range of values are pre-allocated and calls to create one (via
Integer.valueOf
for example) actually result in a reference to a cached object. Intuitively the mostly commonly used boxed numbers in an application often fall within a common range for example 1-10.Savvy readers will realise this means that some equal pairs of Integer objects have reference equality (
==
) and others don’t. You should always use the.equals()
method when comparing boxes numeric types in Java.Byte, Integer and Long all support caching between -128 and 127 but the upper limit of Integers cache is configurable via AutoBoxCacheMax. AggressiveOpts sets the AutoBoxCacheMax to 20000 which means all Integers between -128 and 20000 are cached.
Why caching this range.
@Source The Geeky Way – Java: Autoboxing and -XX:AutoBoxCacheMax
Why caching this range :
This short range are generally used and performance of
public static valueOf( i)
as this method is likely to yield significantly better space and time performance by caching frequently requested values.
Max size of -XX:AutoBoxCacheMax ;
Max cache size can't be more than -Xmx (which is JVM heap size) . Heap size is defined by vm argument -Xmxm .
But, you as soon as JVM initialized, it allocate the memory for caching purpose. But you can't allocate whole (-Xmx in byte)/4 (4byte is size of int) for AutoBoxCache because of other object needed to be loaded and you might end up withjava.lang.OutOfMemoryError: Java heap space
Also, note that for other wrapper classes except Integer , have fixed caching size upto 127 only.
Other wrapper type also have cache mechanism.
@Source Java gotchas - OWASP
The other wrapper classes (Byte, Short, Long, Character) also contain this caching mechanism. The Byte, Short and Long all contain the same caching principle to the Integer object. The Character class caches from 0 to 127. The negative cache is not created for the Character wrapper as these values do not represent a corresponding character. There is no caching for the Float object.
BigDecimal also uses caching but uses a different mechanism. While the other objects contain a inner class to deal with caching this is not true for BigDecimal, the caching is pre-defined in a static array and only covers 11 numbers, 0 to 10:
1 |
|
Cache only for autoboxing rather than built using constructor.
@Source Java Integer Cache - GeeksforGeeks
Java Integer Cache Implementation:
In Java 5, a new feature was introduced to save the memory and improve performance for Integer type objects handling. Integer objects are cached internally and reused via the same referenced objects.
- This is applicable for Integer values in the range between –128 to +127.
- This Integer caching works only on auto-boxing. Integer objects will not be cached when they are built using the constructor.
1 |
|
And do not using constructor to new Integer object, but using autoboxing, because the constructor is deprecated and marked for removal.
@Source Integer (Java Platform SE 8 ) (oracle.com)
Returns an
Integer
instance representing the specifiedint
value. If a newInteger
instance is not required, this method should generally be used in preference to the constructorInteger(int)
, as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
The history of Integer cache and why is -128 to 127.
@Source Java Integer Cache - Javapapers
Actually when this feature was first introduced in Java 5, the range was fixed to –127 to +127. Later in Java 6, the high end of the range was mapped to java.lang.Integer.IntegerCache.high and a VM argument allowed us to set the high number. Which has given flexibility to tune the performance according to our application use case. What is should have been the reason behind choosing this range of numbers from –127 to 127. This is conceived to be the widely most range of integer numbers. The first usage of Integer in a program has to take that extra amount of time to cache the instances.
And more for Integer Cache from
Java Language Specification(JLS)
.
@Source Chapter 5. Conversions and Contexts (oracle.com)
If the value
p
being boxed is an integer literal of typeint
between-128
and127
inclusive (§3.10.1), or the boolean literaltrue
orfalse
(§3.10.3), or a character literal between'\u0000'
and'\u007f'
inclusive (§3.10.4), then leta
andb
be the results of any two boxing conversions ofp
. It is always the case thata
==
b
.Ideally, boxing a primitive value would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rule above is a pragmatic compromise, requiring that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, the rule disallows any assumptions about the identity of the boxed values on the programmer's part. This allows (but does not require) sharing of some or all of these references. Notice that integer literals of type
long
are allowed, but not required, to be shared.This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all
char
andshort
values, as well asint
andlong
values in the range of -32K to +32K.A boxing conversion may result in an
OutOfMemoryError
if a new instance of one of the wrapper classes (Boolean
,Byte
,Character
,Short
,Integer
,Long
,Float
, orDouble
) needs to be allocated and insufficient storage is available.
More details about Java
Question:
- What will happen if the supertypes of a class or interface provide multiple default methods with the same signature?
Answer:
Interface Methods
Default methods and abstract methods in interfaces are inherited like instance methods. However, when the supertypes of a class or interface provide multiple default methods with the same signature, the Java compiler follows inheritance rules to resolve the name conflict. These rules are driven by the following two principles:
Instance methods are preferred over interface default methods.
Consider the following classes and interfaces:
1
2
3
4
5
public class Horse {
public String identifyMyself() {
return "I am a horse.";
}
}
1
2
3
4
5
public interface Flyer {
default public String identifyMyself() {
return "I am able to fly.";
}
}
1
2
3
4
5
public interface Mythical {
default public String identifyMyself() {
return "I am a mythical creature.";
}
}
1
2
3
4
5
6
public class Pegasus extends Horse implements Flyer, Mythical {
public static void main(String... args) {
Pegasus myApp = new Pegasus();
System.out.println(myApp.identifyMyself());
}
}The method
Pegasus.identifyMyself
returns the stringI am a horse.
Methods that are already overridden by other candidates are ignored. This circumstance can arise when supertypes share a common ancestor.
Consider the following interfaces and classes:
1
2
3
4
5
public interface Animal {
default public String identifyMyself() {
return "I am an animal.";
}
}
1
2
3
4
5
public interface EggLayer extends Animal {
default public String identifyMyself() {
return "I am able to lay eggs.";
}
}
1
public interface FireBreather extends Animal { }
1
2
3
4
5
6
public class Dragon implements EggLayer, FireBreather {
public static void main (String... args) {
Dragon myApp = new Dragon();
System.out.println(myApp.identifyMyself());
}
}The method
Dragon.identifyMyself
returns the stringI am able to lay eggs.
If two or more independently defined default methods conflict, or a default method conflicts with an abstract method, then the Java compiler produces a compiler error. You must explicitly override the supertype methods.
Consider the example about computer-controlled cars that can now fly. You have two interfaces (
OperateCar
andFlyCar
) that provide default implementations for the same method, (startEngine
):
1
2
3
4
5
6
7
8
9
10
11
12
public interface OperateCar {
// ...
default public int startEngine(EncryptedKey key) {
// Implementation
}
}
public interface FlyCar {
// ...
default public int startEngine(EncryptedKey key) {
// Implementation
}
}A class that implements both
OperateCar
andFlyCar
must override the methodstartEngine
. You could invoke any of the of the default implementations with thesuper
keyword.
1
2
3
4
5
6
7
public class FlyingCar implements OperateCar, FlyCar {
// ...
public int startEngine(EncryptedKey key) {
FlyCar.super.startEngine(key);
OperateCar.super.startEngine(key);
}
}The name preceding
super
(in this example,FlyCar
orOperateCar
) must refer to a direct superinterface that defines or inherits a default for the invoked method. This form of method invocation is not restricted to differentiating between multiple implemented interfaces that contain default methods with the same signature. You can use thesuper
keyword to invoke a default method in both classes and interfaces.Inherited instance methods from classes can override abstract interface methods. Consider the following interfaces and classes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface Mammal {
String identifyMyself();
}
public class Horse {
public String identifyMyself() {
return "I am a horse.";
}
}
public class Mustang extends Horse implements Mammal {
public static void main(String... args) {
Mustang myApp = new Mustang();
System.out.println(myApp.identifyMyself());
}
}The method
Mustang.identifyMyself
returns the stringI am a horse.
The classMustang
inherits the methodidentifyMyself
from the classHorse
, which overrides the abstract method of the same name in the interfaceMammal
.Note: Static methods in interfaces are never inherited.
Modifiers
The access specifier for an overriding method can allow more, but not less, access than the overridden method. For example, a protected instance method in the superclass can be made public, but not private, in the subclass.
You will get a compile-time error if you attempt to change an instance method in the superclass to a static method in the subclass, and vice versa.
Summary
The following table summarizes what happens when you define a method with the same signature as a method in a superclass.
Superclass Instance Method Superclass Static Method Subclass Instance Method Overrides Generates a compile-time error Subclass Static Method Generates a compile-time error Hides
Note: In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass instance methods—they are new methods, unique to the subclass.
Question:
- Why does adding a String and int take effect?
Answer:
- java - Why does adding a String and an int act this way? - Stack Overflow
- Chapter 15. Expressions (oracle.com)
- String (Java SE 17 & JDK 17) (oracle.com)
- String (Java Platform SE 8 ) (oracle.com)
Overload vs Override, Dynamic binding vs Static binding, Declared type vs Actual type
Myself understanding and note in this topic
Why Java have Dynamic binding and Static binding?
According to the article of What is Static and Dynamic binding in Java with Example (javarevisited.blogspot.com)
If you have more than one method of the same name (method overriding) or two variables of the same name in the same class hierarchy it gets tricky to find out which one is used during runtime as a result of their reference in code. This problem is resolved using static and dynamic binding in Java. For those who are not familiar with the binding operation, its process is used to a link which method or variable to be called as a result of their reference in code.
The difference between static and dynamic binding is a popular Java programming interview question that tries to explore candidates' knowledge on having compiler and JVM finds which methods to call if there is more than one method of the same name as it's the case in method overloading and overriding.
So, in order to solve above problems, Java introduce the dynamic/run-time binding and static/compile binding. And we also known that Java execute compile before interpret, so compile-time is earlier than run-time. For example, in command-line, we have
1 |
|
and that's why JVM first using static binding and then check for dynamic binding.
What are declared type and actual type?
First of all, we should know what is declared type and actual type. An example is
1 |
|
which Animal
is the declared type and Dog
is the actual type of a
.
What is the difference between Override and Overload?
Before we introduce dynamic binding and static binding, we first come to see what is override and overload, according to Defining Methods (The Java™ Tutorials > Learning the Java Language > Classes and Objects) (oracle.com) and Overriding and Hiding Methods (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance) (oracle.com):
Overloading Methods
The Java programming language supports overloading methods, and Java can distinguish between methods with different method signatures. This means that methods within a class can have the same name if they have different parameter lists.
Overriding and Hiding Methods
Instance Methods
An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method.
The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This subtype is called a covariant return type.
Static Methods
If a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass.
The distinction between hiding a static method and overriding an instance method has important implications:
- The version of the overridden instance method that gets invoked is the one in the subclass.
- The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass.
What happen when method calls
According to 5.1.6 Understanding Method Calls
of
Core-Java-Volume-I-Fundamentals-12th-Edition-Cay-S.-Horstmann
:
It is important to understand exactly how a method call is applied to an object. Let’s say we call x.f(args), and the implicit parameter x is declared to be an object of class C. Here is what happens:
- The compiler looks at the declared type of the object and the method name. Note that there may be multiple methods, all with the same name, f, but with different parameter types. For example, there may be a method f(int) and a method f(String). The compiler enumerates all methods called f in the class C and all accessible methods called f in the superclasses of C. (Private methods of the superclass are not accessible.) Now the compiler knows all possible candidates for the method to be called.
- Next, the compiler determines the types of the arguments supplied in the method call. If among all the methods called f there is a unique method whose parameter types are a best match for the supplied arguments, that method is chosen to be called. This process is called overloading resolution. For example, in a call x.f("Hello"), the compiler picks f(String) and not f(int). The situation can get complex because of type conversions (int to double, Manager to Employee, and so on). If the compiler cannot find any method with matching parameter types or if multiple methods all match after applying conversions, the compiler reports an error. Now the compiler knows the name and parameter types of the method that needs to be called
- If the method is private, static, final, or a constructor, then the compiler knows exactly which method to call. (The final modifier is explained in the next section.) This is called static binding. Otherwise, the method to be called depends on the actual type of the implicit parameter, and dynamic binding must be used at runtime. In our example, the compiler would generate an instruction to call f(String) with dynamic binding.
- When the program runs and uses dynamic binding to call a method, the virtual machine must call the version of the method that is appropriate for the actual type of the object to which x refers. Let’s say the actual type is D, a subclass of C. If the class D defines a method f(String), that method is called. If not, D’s superclass is searched for a method f(String), and so on.
It would be time-consuming to carry out this search every time a method is called. Instead, the virtual machine precomputes a method table for each class. The method table lists all method signatures and the actual methods to be called.
The virtual machine can build the method table after loading a class, by combining the methods that it finds in the class file with the method table of the superclass.
When a method is actually called, the virtual machine simply makes a table lookup. In our example, the virtual machine consults the method table for the class D and looks up the method to call for f(String). That method may be D.f(String) or X.f(String), where X is some superclass of D.
There is one twist to this scenario. If the call is super.f(param), then the virtual machine consults the method table of the superclass.
Now, let's see the mystery of the dynamic binding and static binding
note: overloading bind at compile time "static binding" while overriding binds at run time "dynamic binding".
To conclude:
What is Static and Dynamic binding in Java with Example (javarevisited.blogspot.com)
Static binding in Java occurs during Compile time while Dynamic binding occurs during Runtime.
private, final and static methods and variables use static binding and are bonded by the compiler while virtual methods are bonded during runtime based upon runtime object.
Static binding uses Type(Class in Java) information for binding while Dynamic binding uses Object to resolve to bind.
Overloaded methods are bonded using static binding while overridden methods are bonded using dynamic binding at runtime. Here is an example that will help you to understand both static and dynamic binding in Java.
References
Question:
- Overloaded and overridden in Java
- Overriding and Hiding Methods
Answer:
- overriding - Overloaded and overridden in Java - Stack Overflow
- Defining Methods (The Java™ Tutorials > Learning the Java Language > Classes and Objects) (oracle.com)
- Overriding and Hiding Methods (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance) (oracle.com)
Question:
- Overriding vs Hiding
Answer:
- inheritance - Overriding vs Hiding Java - Confused - Stack Overflow
- Overriding and Hiding Methods (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance) (oracle.com)
- Overriding Vs Hiding (Wiki forum at Coderanch)
- Variable and Method Hiding in Java | Baeldung
Question:
- Dynamic binding/run-time binding vs Static binding/compile-time binding
Answer:
- java - Static Binding and Dynamic Binding - Stack Overflow
- Also see
5.1.6 Understanding Method Calls
ofCore-Java-Volume-I-Fundamentals-12th-Edition-Cay-S.-Horstmann
- Understanding Class Members (The Java™ Tutorials > Learning the Java Language > Classes and Objects) (oracle.com)
- Polymorphism (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance) (oracle.com)
- What is Static and Dynamic binding in Java with Example (javarevisited.blogspot.com)
- Static Vs. Dynamic Binding in Java - Stack Overflow
- Skeleton Coder: Java Tutorials: Overloading is compile-time binding
- What is Static and Dynamic binding in Java with Example (javarevisited.blogspot.com)
- inheritance - Java dynamic binding and method overriding - Stack Overflow
- oop - What is the difference between dynamic and static polymorphism in Java? - Stack Overflow
Question:
- compile-time error when calling a subclass method using superclass reference?
Answer:
Question:
- Static type(not static binding)
Answer:
Other Question
Question:
- Does casting change the declared/reference type at run-time?
Answer:
- java - Does casting change the declared/reference type at run-time? - Stack Overflow
- Explicit type casting example in Java - Stack Overflow
Question:
- Class hierarchy terms, ancestor- vs. parent-class
Answer:
Question:
- Is constructor a member or method of class
Answer:
- Java: How can a constructor return a value? - Stack Overflow
- java "void" and "non void" constructor - Stack Overflow
- Chapter 8. Classes (oracle.com)
- Also see the
4.3.4 First Steps with Constructors
ofCore-Java-Volume-I-Fundamentals-12th-Edition-Cay-S.-Horstmann
Question:
- The sequence of constructor was invoked when subclass object is constructed?
Answer:
- Also see the
5.1.3 Subclass Constructors
ofCore-Java-Volume-I-Fundamentals-12th-Edition-Cay-S.-Horstmann
Quesrion:
- What is the difference between
==
andjava.lang.Object.equals()
?
Answer:
- identity - What is the difference between == and equals() in Java? - Stack Overflow
- Object (Java SE 17 & JDK 17) (oracle.com)
Question:
- How do I compare Strings in Java?
Answer:
- How do I compare strings in Java? - Stack Overflow
- How can I compare two strings in java and define which of them is smaller than the other alphabetically? - Stack Overflow
Qusetion:
- How to check if object is null or not?
Answer:
- java - How to check if object is null or not except == null - Stack Overflow
- Objects (Java Platform SE 8 ) (oracle.com)
Question:
- Is java pass-by-value or pass-by-reference
Answer:
- Java is Pass-by-Value, Dammit! | JavaDude.com
- methods - Is Java "pass-by-reference" or "pass-by-value"? - Stack Overflow
- language agnostic - What's the difference between passing by reference vs. passing by value? - Stack Overflow
- Also see the
4.5 Method Parameters
ofCore-Java-Volume-I-Fundamentals-12th-Edition-Cay-S.-Horstmann
Question:
- What is reference type and value type in Java?
Answer:
- Value type and reference type - Wikipedia
- Also see the
2.1 Mystery of the Walrus
of 2.1 Mystery of the Walrus · Hug61B (gitbooks.io) - java - What's the difference between primitive and reference types? - Stack Overflow
Question:
- How to call object member in static method
Answer:
- Static method in java - Stack Overflow
- java - objects - calling object instance inside a static method - Stack Overflow
Question:
- Hiding vs Shadow
Answer:
- Difference in Method Overloading, Overriding, Hiding, Shadowing and Obscuring in Java and Object-Oriented Programming? | Java67
- Variable Hiding and Variable Shadowing in Java - Scaler Topics
Question:
- Interface vs Abstract Class
Answer:
- java - How should I have explained the difference between an Interface and an Abstract class? - Stack Overflow
- Also see the
6.1.3 Interfaces and Abstract Classes
ofCore-Java-Volume-I-Fundamentals-12th-Edition-Cay-S.-Horstmann
Question:
- How to convert String into double?
Answer:
Question:
- Why does accessing an array element take constant time?
Answer:
Style about Java
Question:
- Is calling static methods via an object "bad form"?
Answer:
Question:
- When to use
var
in Java ?
Answer:
- Local Variable Type Inference: Style Guidelines (archive.org)
- Also see the
4.3.5 Declaring Local Variables with var
and6.3.6 Anonymous Inner Classes
ofCore-Java-Volume-I-Fundamentals-12th-Edition-Cay-S.-Horstmann