Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the overloading and rewriting methods of Java and JVM

2025-01-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

In this article, the editor introduces in detail "what are the reloading and rewriting methods of Java and JVM" with detailed contents, clear steps and proper handling of details. I hope that this article "what is the reloading and rewriting methods of Java and JVM" can help you solve your doubts.

1. Case void invoke (Object obj, Object... Args) {...} void invoke (String s, Object obj, Object...) Args) {...} invoke (null, 1); / / call the second invoke method invoke (null, 1,2); / / call the second invoke method invoke (null, new Object [] {1}); / / only call the first invoke method by manually bypassing syntax sugar with variable length arguments.

An API defines two overloaded methods with the same name:

The first to receive an Object and declare it as Object... Variable length parameter of

The second one receives a String, an Object, and a declaration as Object. Variable length parameter of

To call the first method, pass the parameter (null, 1), that is, the actual parameter corresponding to the formal parameter declared as Object is null, while the variable length parameter corresponds to 1.

Method overloading with variable length parameters is discouraged because the Java compiler may not be able to decide which target method should be called.

In this case, the compiler reports an error and prompts that the method call is ambiguous. However, why on earth does the Java compiler directly recognize my method call as a call to the second method?

How does the Java virtual machine identify the target method?

two。 Reloading and rewriting

There are multiple in the same class:

Same name.

The parameter type is the same

This limitation can be bypassed by the bytecode tool, and after compilation is complete, you can add methods with the same method name and parameter type but different return types to the class file. When this class, which includes multiple methods with the same name, the same parameter type, but different return types, appears on the user classpath of the Java compiler, how does it determine which method to call?

The current version of the Java compiler directly selects the first method name and the method that matches the parameter type. Moreover, it determines whether it can be compiled and whether a value conversion is required based on the return type of the selected method.

The overloaded method can be identified during the compilation process. For each method call, the Java compiler selects the overloaded method based on the declaration type of the passed parameter (note that it is different from the actual type). The selection process is divided into three stages:

Select the overloading method without considering the automatic loading and unpacking of basic types and variable length parameters.

If the adaptation method is not found in the first stage, the overloading method is selected when automatic loading and unpacking is allowed, but variable length parameters are not allowed.

If the adaptation method is not found in the second stage, the overloading method is selected when automatic loading and unpacking and variable length parameters are allowed.

If the Java compiler finds multiple adaptation methods at the same stage, it will choose one of the most appropriate, and the key to the degree of appropriateness is the inheritance of formal parameter types.

When null is passed in, it matches either the formal parameter declared as Object in the first method or the formal parameter declared as String in the second method. Because String is a subclass of Object, the Java compiler thinks the second method is more appropriate.

In addition to methods in the same class, overloading can also act on methods inherited from this class. If the subclass defines a method with the same name as the non-private method in the parent class, and the parameter types of the two methods are different, then in the subclass, the two methods also constitute overloading.

If the subclass definition has the same name as the method of the non-private method in the parent class, and the parameter types of the two methods are the same, what is the relationship between the two methods:

If both are static methods, the methods in the subclass hide the methods in the parent class

If none of them are static, the method of the subclass overrides the method in the parent class

Java's method rewriting is a manifestation of polymorphism: allowing subclasses to inherit some of the functionality of the parent class while having their own unique behavior.

The override call selects the actual target method based on the dynamic type of the caller.

Static binding and dynamic binding of 3.JVM

The key of the Java virtual machine identification method lies in the class name, method name and method descriptor (method descriptor).

The method descriptor consists of the parameter type and return type of the method.

In the same class, if multiple methods with the same name and the same descriptor appear at the same time, the Java virtual machine reports an error during the validation phase of the class.

The Java virtual machine is different from the Java language in that it does not restrict methods with the same name and parameter type but different return types to appear in the same class. For the bytecode that calls these methods, because the method descriptor attached to the bytecode contains the return type, the Java virtual machine can accurately identify the target method.

The JVM method rewriting decision is also based on the method descriptor.

If a subclass defines a method with the same name as a non-private, non-static method in the parent class, JVM will determine that the method is overridden only if the parameter type and return type of the two methods are the same.

In the case of overrides in Java but not in Java virtual machines, the compiler implements the rewriting semantics of Java by generating bridging methods [2].

Since the distinction between overloaded methods has been completed during the compilation phase, it can be considered that there is no concept of overloading in JVM. Therefore, some articles will

Overloading is called static binding (static binding) or compile-time polymorphism (compile-time polymorphism)

Rewriting is called dynamic binding (dynamic binding)

This is not entirely true in the context of JVM, because overloaded methods in a class may be overridden by its subclasses, so JVM compiles all calls to non-private instance methods to types that require dynamic binding.

JVM's:

Static binding means that the target method can be directly identified when parsing.

Dynamic binding means to identify the target method according to the dynamic type of the caller during the run.

The instructions related to invocation in Java bytecode are:

Invokestatic: calling static methods

Invokespecial: call the private instance method, constructor, and call the instance method or constructor of the parent class using the super keyword, and the default method of the implemented interface

Invokevirtual: used to call non-private instance methods

Invokeinterface: used to call interface methods

Invokedynamic: it is more complex to call dynamic methods

Compile and generate these four invocation instructions.

Interface customer {boolean isVIP ();} class merchant {public double discount price (double original price, a customer) {return original price * 0.8d }} class profiteer extends merchant {@ Override public double discount price (double original price, a customer) {if (some customer .isVIP ()) {/ / invokeinterface return original price * price discrimination (); / / invokestatic} else {return super. Discounted price (original price, a customer); / / invokespecial}} public static double price discrimination () {/ / our algorithm is so rough that we should use the customer's city as the seed of the random number generator. Return new Random () / / invokespecial .nextDouble () / / invokevirtual + 0.8d;}}

The Merchant class defines a member method called discounted Price, which receives a double type parameter and a customer type parameter.

Here "customer" is an interface, and an interface method "isVIP" is defined.

The method of the "profiteer" class first calls the customer # isVIP, which is compiled into an invokeinterface instruction

If the customer is VIP, call a static method of the profiteer class called "price discrimination". The call will be compiled into an invokestatic instruction

If the customer is not VIP, the discounted price method of the parent class is called through super. The call will be compiled into an invokespecial instruction

The constructor of the Random class is called in the static method "price discrimination". The call is compiled into an invokespecial instruction. Then call the nextDouble method in the Random class with the newly created Random object as the caller. The call is compiled into an invokevirutal instruction.

For invokestatic and invokespecial, the Java virtual machine can directly identify specific target methods.

For invokevirtual and invokeinterface, in most cases, the virtual machine needs to determine the specific target method according to the dynamic type of the caller during execution.

If there is one and only one method for virtual machine to determine the target, for example, the target method is marked as final [3] [4], it can determine the target method directly without dynamic type.

4. Symbolic reference to invocation instruction

During compilation, we do not know the specific memory address of the target method. Therefore, the Java compiler temporarily uses symbolic references to represent the target method.

This symbolic reference includes the name of the class or interface in which the target method is located, as well as the method name and method descriptor of the target method.

Symbol references are stored in the constant pool of the class file. Depending on whether the target method is an interface method, these references can be divided into:

Interface symbol reference

Non-interface symbol reference

/ / in the constant pool of profiteer .class, # 16 is the interface symbol reference, pointing to the interface method "customer .isVIP ()". # 22 is a non-interface symbol reference that points to the static method "profiteers. Price discrimination ()". $javap-v profiteer. Class. Constant pool:... # 16 = InterfaceMethodref # 27.27. / / customer. IsVIP: () Z. # 22 = Methodref # 1. profiteers 33 / / profiteers. Price discrimination: () D.

Before executing bytecode that uses symbolic references, JVM parses these [symbolic references] and replaces them with [actual references].

For [non-API symbol reference], assuming that the class pointed to by the [symbol reference] is C, JVM follows the following steps:

Find the method that matches the name and descriptor in C

If not, search the parent class of C until the Object class

If it has not been found, search in the interface directly or indirectly implemented by C, the target method obtained in this step must be non-private, non-static, and if the target method is in the interface that is indirectly implemented, it must satisfy that there are no other qualified target methods between C and the interface. If there are multiple qualified target methods, any one of them is returned.

So the static method can also be called through subclasses. The static method of the subclass hides (this is not an override) the static method of the same name and descriptor in the parent class.

For an interface symbol reference, assuming that the interface to which the symbol reference points is I, the Java virtual machine looks for it as follows.

Find a method in I that matches the name and descriptor.

If not, search in the public instance method in the Object class.

If it is not found, search in the hyperinterface of I. The requirements of the search results for this step are consistent with the requirements of step 3 for non-interface symbol references.

After the above parsing steps, the symbolic reference is resolved to the actual reference:

For a statically bindable method call, the actual reference is a pointer to the method

For method calls that need to be dynamically bound, the actual reference is an index of the method table

5. Summary and practice

This paper introduces the target recognition method of Java and Java virtual machine.

In the Java method:

Overloading, between methods with the same method name but different parameter types

Overridden, between methods with the same method name and the same parameter type

JVM identifies a method in addition to the method name and parameter type, as well as the return type.

JVM's:

Static binding: the situation in which the target method can be directly identified when parsing

Dynamic binding, the target method needs to be identified according to the dynamic type of the caller during the run. Since the Java compiler has distinguished between overloaded methods, it can be considered that there is no overloading in JVM

In the class file, the Java compiler uses symbolic references to refer to the target method. Before the invocation instruction is executed, the symbolic reference that comes with it needs to be resolved to the actual reference. For method calls that can be statically bound, the actual reference is the pointer to the target method. For method calls that require dynamic binding, the actual reference is auxiliary dynamic binding information.

The rewriting of Java is not consistent with the rewriting in the Java virtual machine, but the compiler makes up for it by generating bridging methods.

After reading this, the article "what are the reloading and rewriting methods of Java and JVM" has been introduced. If you want to master the knowledge points of this article, you still need to practice and use it yourself to understand it. If you want to know more about related articles, welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report