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 is the unknown special method in Java?

2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

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

The main content of this article is to explain "what are the unknown special methods in Java". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "what is the unknown special method in Java"?

Visibility

When you create a nested class, its private variables and methods are visible to the upper class. This is used in immutable nested Builder mode. This is a behavior that has been defined in the Java language specification.

Package synthetic;//java framework www.1b23.compublic class SyntheticMethodTest1 {private An aObj = new A (); public class A {private int i;} private class B {private int i = aObj.i;} public static void main (String [] args) {SyntheticMethodTest1 me = new SyntheticMethodTest1 (); me.aObj.i = 1; B bObj = me.new B (); System.out.println (bObj.i);}}

How does JVM handle this? It doesn't know what inner classes or nested classes are. JVM treats all classes equally and considers them to be top-level classes. All classes are compiled into top-level classes, and those inner classes are generated after compilation. $... The class file for class.

$ls-Fart../ SyntheticMethodTest2 $A.class MyClass.java SyntheticMethodTest4.java SyntheticMethodTest2.javaSyntheticMethodTest2.class SyntheticMethodTest3.java. / MyClassSon.java SyntheticMethodTest1.java

If you create an inner class, it will be completely compiled into a top-level class.

So how are these private variables accessed by external classes? If they are private variables of a top-level class (and they are), why do other classes have direct access to these variables?

Javac solves this problem by generating a synthetic method for any private field, method, or constructor if they are also used by other top-level classes. These synthetic methods are used to access the original private variable / method / constructor. The generation of these methods is also smart: such methods are generated only if they are actually used by external classes.

Package synthetic;import java.lang.reflect.Constructor;import java.lang.reflect.Method;//java framework www.1b23.compublic class SyntheticMethodTest2 {public static class A {private A () {} private void x () {};} public static void main (String [] args) {AA = new A (); A.X = 2; A.X (); System.out.println (A.X) For (Method m: A.class.getDeclaredMethods ()) {System.out.println (String.format ("X", m.getModifiers ()) + "+ m.getName ());} System.out.println ("-") For (Method m: A.class.getMethods ()) {System.out.println (String.format ("X", m.getModifiers ()) + "+ m.getReturnType (). GetSimpleName () +" + m.getName ());} System.out.println ("-") For (Constructor c: A.class.getDeclaredConstructors ()) {System.out.println (String.format ("X", c.getModifiers ()) + "+ c.getName ());}

The names of these generated methods depend on the specific implementation, and it's hard to say what they are called in the end. I can only say that on the platform I am running, the output of the above program looks like this:

200001008 access$100001008 access$200001008 access$300000002 Xmuri 00000111 void wait00000011 void wait00000011 void wait00000001 boolean equals00000001 String toString00000101 int hashCode00000111 Class getClass00000111 void notify00000111 void notifyAll--00000002 synthetic.SyntheticMethodTest2 $A00001000 synthetic.SyntheticMethodTest2 $A

In the above program, we assign a value to the variable x and then call a method with the same name. This triggers the compiler to generate the corresponding synthetic method. You will see that it generates three methods, which should be the setter and getter methods of the x variable, and a synthetic method corresponding to the x () method. These methods do not exist in the list returned in the getMethods method because they are synthetic methods and cannot be called directly. From this point of view, they are similar to proprietary methods.

Take a look at the constants defined in java.lang.reflect.Modifier to see what these hexadecimal numbers represent:

00001008 SYNTHETIC | STATIC00000002 PRIVATE00000111 NATIVE | FINAL | PUBLIC00000011 FINAL | PUBLIC00000001 PUBLIC00001000 SYNTHETIC

Two of the list are constructors. There is also a private method and a synthetic method. This private method exists because we do define it. The synthetic method appears because we call its internal private members from the external class. So far, there has been no bridge method.

Generics and inheritance

So far, it looks good. But we haven't seen the "volatile" method yet.

If you look at the source code of java.lang.reflect.Modifier, you will see that the constant 0x00000040 has been defined twice. One is defined as VOLATILE, and the other is BRIDGE (the latter is private inside the package and is not open to the public).

If you want to have the volatile method, just write a simple program:

Package synthetic;import java.lang.reflect.Method;import java.util.LinkedList;//java framework www.1b23.compublic class SyntheticMethodTest3 {public static class MyLink extends LinkedList {@ Overridepublic String get (int I) {return "" } public static void main (String [] args) {for (Method m: MyLink.class.getDeclaredMethods ()) {System.out.println (String.format ("X", m.getModifiers ()) + "+ m.getReturnType (). GetSimpleName () +" + m.getName ());}

The linked list has a get (int) method that returns String. Let's not talk about whether the code is neat or not. This is just a sample code. Of course, the same problem can occur with clean code, but the more complex the code, the harder it is to locate the problem.

The output looks like this:

00000001 String get00001041 Object get

There are two get methods. One is the one in the code, and the other is the synthetic and bridge methods. Decompiled with javap looks like this:

Public java.lang.String get (int); Code: Stack=1, Locals=2, Args_size=2 0: ldc # 2; / / String 2: areturn LineNumberTable: line 12: 0public java.lang.Object get (int); Code: Stack=2, Locals=2, Args_size=2 0: aload_0 1: iload_1 2: invokevirtual # 3; / / Method get: (I) Ljava/lang/String; 5: areturn

Interestingly, the signatures of the two methods are exactly the same, except for the different return types. This is legal in JVM, but not allowed in the Java language. This method of bridge does nothing but call the original method.

Why do we need this synthetic method, and who will call it? For example, there is now a piece of code that wants to call a get (int) method of a variable that is not of type MyLink:

List a = new MyLink (); Object z = a.get (0)

It cannot call a method that returns String because there is no such method in List. To explain it more clearly, let's rewrite the add method instead of the get method:

Package synthetic;import java.util.LinkedList;import java.util.List;public class SyntheticMethodTest4 {public static class MyLink extends LinkedList {@ Overridepublic boolean add (String s) {return true;}} public static void main (String [] args) {List a = new MyLink (); a.add ("); a.add (13);}}

We'll find this bridge method.

Public boolean add (java.lang.Object); Code: Stack=2, Locals=2, Args_size=2 0: aload_0 1: aload_1 2: checkcast # 2; / / class java/lang/String 5: invokevirtual # 3; / / Method add: (Ljava/lang/String;) Z 8: ireturn

Not only does it call the original method, it also does type checking. This check is done at run time and is not done by JVM itself. As you might expect, an exception is thrown at line 18:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at synthetic.SyntheticMethodTest4 $MyLink.add (SyntheticMethodTest4.java:1) at synthetic.SyntheticMethodTest4.main (SyntheticMethodTest4.java:18) so far, I believe you have a better understanding of "what is the unknown special method in Java". You might as well do it in practice! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

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

Internet Technology

Wechat

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

12
Report