This article is referred to -bjbsair.com/2020-03-22/…

Jad decomcompiling tool, no longer updated and only supports JDK1.4, does not affect its powerful features.

Basic usage: jad xxx.class, which generates a direct readable xxx.jad file.

Automatic unpacking

For conversion between primitive and wrapper types, the automatic unboxing is done using xxxValue() and valueOf() methods. Decomcompiling using JAD shows this process:

public class Demo { public static void main(String[] args) { int x = new Integer(10); Integer y = x; // automatic packing}}Copy the code

Decompiling results:

public class Demo  
{  
    public Demo(){} public static void main(String args[]) { int i = (new Integer(10)).intValue(); // intValue() Unpack Integerinteger = Integer.valueOf(i);   // valueOf()装箱  
    }  
}
Copy the code

The foreach syntactic sugar

We can foreach a sugar for iterating over an array type and convert it directly to a for loop:

Int [] arr = {1, 2, 3, 4, 5};for(int item: arr) { System.out.println(item); Int ai[] = {1, 2, 3, 4, 5}; int ai1[] = ai; int i = ai1.length; / / convertforcyclefor(int j = 0; j < i; j++)  
{  
    int k = ai1[j];  
    System.out.println(k);  
}
Copy the code

Iterators are used to iterate over container classes:

import java.io.PrintStream;  
import java.util.*;  
  
public class Demo  
{  
    public Demo() {}  
    public static void main(String args[])  
    {  
        ArrayList arraylist = new ArrayList();  
        arraylist.add(Integer.valueOf(1));  
        arraylist.add(Integer.valueOf(2));  
        arraylist.add(Integer.valueOf(3));  
        Integer integer; / / useforLoop +Iterator, similar to linked list iteration: //for(ListNode cur = head; cur ! = null; System.out.println(cur.val)){ // cur = cur.next; / /}for(Iterator iterator = arraylist.iterator(); iterator.hasNext(); System.out.println(integer))  
            integer= (Integer)iterator.next(); }}Copy the code

Arrays.asList(T…)

Familiar with Arrays. AsList () T… The asList() method cannot pass an array of primitive types. It must be wrapped as a wrapper, otherwise the size of the generated list is always 1:

import java.util.*; public class Demo { public static void main(String[] args) { int[] arr1 = {1, 2, 3}; Integer[] arr2 = {1, 2, 3}; List lists1 = Arrays.asList(arr1); List lists2 = Arrays.asList(arr2); System.out.println(lists1.size()); // 1 System.out.println(lists2.size()); / / 3}}Copy the code

From the decompilation result, we can explain why we return a List of size 1 when we pass in an array of primitive type:

// Decomcompiled file import java.io.PrintStream; import java.util.Arrays; import java.util.List; public class Demo { publicDemo() {} public static void main(String args[]) { int ai[] = { 1, 2, 3 }; Integer ainteger[] = {integer.valueof (1), integer.valueof (2), integer.valueof (3)}; Array.size () returns 1 list list = array.asList (new int[][] {ai}); // Array.size () returns 1 list list = array.asList (new int[][] {ai}); List list1 = Arrays.asList(ainteger); System.out.println(list.size()); System.out.println(list1.size()); }}Copy the code

As you can see from the above results, passing in an array of primitive type is converted to a two-dimensional array, and the array is **new int[1][arr.length]**. Calling list.size() returns 1.

annotations

Classes, interfaces, enumerations, and annotations in Java can all be considered class types. Use jad to see what @interface is converted to:

import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
  
@Retention(RetentionPolicy.RUNTIME)  
public @interface Foo{  
  String[] value();  
  boolean bar();  
}
Copy the code

Looking at the decompiled code, you can see:

  • The custom Annotation class Foo is converted to interface Foo and inherits the Annotation interface
  • Value () and bar() from the custom interface are converted to abstract methods
import java.lang.annotation.Annotation;  
  
public interface Foo  
    extends Annotation  
{  
    public abstract String[] value();  
  
    public abstract boolean bar();  
}
Copy the code

Annotations are usually used in conjunction with reflection, and since custom annotations are eventually converted to interfaces and attributes in annotations are converted to abstract methods in the interface, the corresponding abstract methods can be called from the interface instance after reflection:

import java.util.Arrays;  
  
@Foo(value={"sherman"."decompiler"}, bar=true)  
public class Demo{  
    public static void main(String[] args) {  
        Foo foo = Demo.class.getAnnotation(Foo.class);  
        System.out.println(Arrays.toString(foo.value())); // [sherman, decompiler]  
        System.out.println(foo.bar());                    // true}}Copy the code

The enumeration

Enumeration classes are well understood by jad decompression.

An empty enumeration

Define an empty enumeration class:

public enum DummyEnum {  
}
Copy the code

Use jad to decompress the result:

  • Custom enumerated classes are converted to final classes and inherit enums
  • A private constructor for two arguments (name, odinal) is provided, and the constructor for the parent class is called. Note that there is a constructor even if no arguments are provided, where name is the name of the enumeration instance and odinal is the index number of the enumeration instance
  • Initialize an empty array $VALUES of private static final custom type
  • The clone() method returns a shallow copy of the internal $values. This method, combined with a private constructor, perfectly implements the singleton pattern. Consider whether the values() method functions like getInstance() in the singleton pattern: valueOf(String s) calls the parent Enum valueOf method and returns it
Public final class DummyEnum extends Enum {getInstance() public static DummyEnum[]values()  
    {  
        return (DummyEnum[])$VALUES.clone(); } public static DummyEnum valueOf(String s) {return(DummyEnum)Enum.valueOf(DummyEnum, s); } private DummyEnum(String s, int I) {super(s, I); private DummyEnum(String s, int I); } // Initialize a private static final empty array private static final DummyEnum$VALUES[] = new DummyEnum[0];  
  
}  

Copy the code

Enumeration containing abstract methods

Enumeration classes can also contain abstract methods, but the enumeration instance must be defined and the abstract method overridden immediately, as follows:

public enum DummyEnum {  
    DUMMY1 {  
        public void dummyMethod() {  
            System.out.println("[1]: implements abstract method in enum class");  
        }  
    },  
  
    DUMMY2 {  
        public void dummyMethod() {  
            System.out.println("[2]: implements abstract method in enum class"); }}; abstract void dummyMethod(); }Copy the code

Let’s decompile to see what happens:

  • A final class becomes an abstract class: it makes sense that a class with abstract methods is an abstract class
  • Have two public static final DUMMY1, DUMMY2, the members of the two instance initialization process is on the static block of code, and instance directly to rewrite the abstract methods in the process, is similar to the form of an anonymous inner class.
  • The array **$VALUES[]** is initialized to place an enumeration instance

Any other changes?

In the decomcompiled DummyEnum class, there are abstract methods, which enumeration instances override during initialization in static code blocks. In Java, abstract methods and abstract method overrides are placed in a single class and can only be done in inner class form. Therefore, the second point above should say that an achievement is initialized in an internal form.

Dummyenum.class = dummyenum.class = dummyenum.class = dummyenum.class = dummyenum.class = dummyenum.class = dummyenum.class

  • DummyEnum$1.class
  • DummyEnum$2.class

A. Class file appears in JavaInnerClass, these two files are present in support of the anonymous InnerClass initialization statement above.

import java.io.PrintStream;  
  
public abstract class DummyEnum extends Enum  
{  
    public static DummyEnum[] values()  
    {  
        return (DummyEnum[])$VALUES.clone();  
    }  
  
    public static DummyEnum valueOf(String s)  
    {  
        return(DummyEnum)Enum.valueOf(DummyEnum, s); } private DummyEnum(String s, int i) { super(s, i); } // abstract void dummyMethod(); Public static final DummyEnum DUMMY1; public static final DummyEnum DUMMY2; private static final DummyEnum$VALUES[]; Static {DUMMY1 = new DummyEnum("DUMMY1", 0) {  
            public void dummyMethod()  
            {  
                System.out.println("[1]: implements abstract method in enum class"); }}; DUMMY2 = new DummyEnum("DUMMY2", 1) {  
            public void dummyMethod()  
            {  
                System.out.println("[2]: implements abstract method in enum class"); }}; // Initialize the array of this class$VALUES= (new DummyEnum[] { DUMMY1, DUMMY2 }); }}Copy the code

A normal enumerated class

In practice, enumeration classes usually take the form of a constructor with two arguments (int code, Sring MSG) that can be returned as a status code. The Enum class actually provides a protected constructor with two arguments. To avoid ambiguity, we make the constructor of the Enum class three, using jad:

The biggest change is that the private constructor now has five arguments instead of two, and internally still passes the first two arguments to the parent class via super, leaving the remaining three arguments that are actually supplied by itself. Conceivably, if the custom enumerated class provides only one argument, the resulting private constructor in the underlying code should have three arguments, the first two still passed to the parent class via super.

public final class CustomEnum extends Enum  
{  
    public static CustomEnum[] values()  
    {  
        return (CustomEnum[])$VALUES.clone();  
    }  
  
    public static CustomEnum valueOf(String s)  
    {  
        return (CustomEnum)Enum.valueOf(CustomEnum, s);  
    }  
  
    private CustomEnum(String s, int i, int j, String s1, Object obj)  
    {  
        super(s, i);  
        code = j;  
        msg = s1;  
        data = obj;  
    }  
  
    public static final CustomEnum FIRST;  
    public static final CustomEnum SECOND;  
    public static final CustomEnum THIRD;  
    private int code;  
    private String msg;  
    private Object data;  
    private static final CustomEnum $VALUES[];  
  
    static   
    {  
        FIRST = new CustomEnum("FIRST", 0, 10010, "first", Long.valueOf(100L));  
        SECOND = new CustomEnum("SECOND", 1, 10020, "second"."Foo");  
        THIRD = new CustomEnum("THIRD", 2, 10030, "third", new Object());  
        $VALUES= (new CustomEnum[] { FIRST, SECOND, THIRD }); }} ' 'this article reference text -http://bjbsair.com/2020-03-22/tech-info/5702/! [by JAD decompiler I found many interesting code] (HTTP: / / https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/3/23/1710806395ac7e2f~tplv- T2oaga2asx-image.image) JAD decompression tool, no longer updated, and only supports JDK1.4, but does not affect its powerful function. Basic usage: jad xxx.class, which generates a direct readable xxx.jad file. ----- For conversion between primitive and wrapper types, xxxValue() and valueOf() are used to complete automatic unboxing. Using jad to decompile, you can see the process:Copy the code

public class Demo { public static void main(String[] args) { int x = new Integer(10); Integer y = x; // automatic packing}}

Decompiling results:Copy the code

public class Demo

{

public Demo(){}

public static void main(String args[]) { int i = (new Integer(10)).intValue(); // intValue() unboxing Integer Integer = integer.valueof (I); // valueOf() box}Copy the code

}

Foreach sugar ---------- Foreach sugar can be converted directly to array types when iterating overforCycle:Copy the code

Int [] arr = {1, 2, 3, 4, 5}; for(int item: arr) { System.out.println(item); }}

Int ai[] = {1, 2, 3, 4, 5}; int ai1[] = ai; int i = ai1.length; // convert to for loop for(int j = 0; j < i; j++) { int k = ai1[j]; System.out.println(k); }

Iterators are used to iterate over container classes:Copy the code

import java.io.PrintStream;

import java.util.*;

public class Demo { public Demo() {} public static void main(String args[]) { ArrayList arraylist = new ArrayList(); arraylist.add(Integer.valueOf(1)); arraylist.add(Integer.valueOf(2)); arraylist.add(Integer.valueOf(3)); Integer integer; // For (ListNode cur = head; cur ! = null; System.out.println(cur.val)){ // cur = cur.next; // } for(Iterator iterator = arraylist.iterator(); iterator.hasNext(); System.out.println(integer)) integer = (Integer)iterator.next(); }}

Arrays.asList(T...) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - familiar with Arrays. AsList () T... The asList() method cannot pass an array of primitive types. It must be wrapped as a wrapper, otherwise the size of the generated list is always 1:Copy the code

import java.util.*; public class Demo { public static void main(String[] args) { int[] arr1 = {1, 2, 3}; Integer[] arr2 = {1, 2, 3}; List lists1 = Arrays.asList(arr1); List lists2 = Arrays.asList(arr2); System.out.println(lists1.size()); // 1 System.out.println(lists2.size()); / / 3}}

From the decompilation result, we can explain why we return a List of size 1 when we pass in an array of primitive type:Copy the code

// Decomcompiled file import java.io.PrintStream; import java.util.Arrays; import java.util.List;

public class Demo

{

public Demo() {}

public static void main(String args[]) { int ai[] = { 1, 2, 3 }; Integer ainteger[] = {integer.valueof (1), integer.valueof (2), integer.valueof (3)}; Array.size () returns 1 list list = array.asList (new int[][] {ai}); // Array.size () returns 1 list list = array.asList (new int[][] {ai}); List list1 = Arrays.asList(ainteger); System.out.println(list.size()); System.out.println(list1.size()); }Copy the code

}

As you can see from the above results, passing in an array of primitive type is converted to a two-dimensional array, and the array is **new int[1][arr.length]**. Calling list.size() returns 1. Annotations - Classes, interfaces, enumerations, and annotations in Java can all be considered class types. Use jad to see what @interface is converted to:Copy the code

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)

public @interface Foo{

String[] value();

boolean bar();

}

Looking at the decomcompiled code, you can see that: * The custom Annotation class Foo is converted to interface Foo, and the inherited Annotation interface * Value () and bar() from the definition interface are converted to abstract methodsCopy the code

import java.lang.annotation.Annotation;

public interface Foo

extends Annotation

{

public abstract String[] value();

public abstract boolean bar();  
Copy the code

}

Annotations are usually used in conjunction with reflection, and since custom annotations are eventually converted to interfaces and attributes in annotations are converted to abstract methods in the interface, the corresponding abstract methods can be called from the interface instance after reflection:Copy the code

import java.util.Arrays;

@Foo(value={“sherman”, “decompiler”}, bar=true)

public class Demo{

public static void main(String[] args) {

Foo foo = Demo.class.getAnnotation(Foo.class);

System.out.println(Arrays.toString(foo.value())); // [sherman, decompiler]

System.out.println(foo.bar()); // true

}

}

Enumeration -- Enumeration classes are well understood by jad decompression.# # # empty enumerationDefine an empty enumeration class:Copy the code

public enum DummyEnum {

}

Using JAD decomcompiling to see the results: * The custom enumeration class is converted to final, and inherits Enum * that provides a private constructor for two arguments (name, odinal), and calls the constructor for the parent class. Note that there is a constructor even if no arguments are provided, where name is the name of the enumeration instance and odinal is the index number of the enumeration instance$VALUES** * provides two public static methods: the values() method passescloneThe () method returns to the interior$VALUESA shallow copy of. This method, combined with a private constructor, perfectly implements the singleton pattern. Consider whether the values() method functions like getInstance() in the singleton pattern: valueOf(String s) calls the parent Enum valueOf method and returns itCopy the code

public final class DummyEnum extends Enum

{

// The function is the same as the singleton getInstance() method

public static DummyEnum[] values()

{

return (DummyEnum[])VALUES[] = new DummyEnum[0];

}


### contains enumerations of abstract methodsEnumeration classes can also contain abstract methods, but the enumeration instance must be defined and the abstract method overridden immediately, as follows:Copy the code

public enum DummyEnum { DUMMY1 { public void dummyMethod() { System.out.println(“[1]: implements abstract method in enum class”); }},

DUMMY2 { public void dummyMethod() { System.out.println("[2]: implements abstract method in enum class"); }}; abstract void dummyMethod();Copy the code

}

* Final class becomes abstract class: It is easy to understand with the class nature of the abstract methods is more abstract class * two public static final DUMMY1, DUMMY2, the members of the two instance initialization process is on the static block of code, and the instance directly to rewrite the abstract methods in the process, is similar to the form of an anonymous inner class. * * * an array$VALUES[]** Are there any other changes to putting enumeration instances into the initialization? In the decomcompiled DummyEnum class, there are abstract methods, which enumeration instances override during initialization in static code blocks. In Java, abstract methods and abstract method overrides are placed in a single class and can only be done in inner class form. Therefore, the second point above should say that an achievement is initialized in an internal form. * DummyEnum * DummyEnum * DummyEnum * DummyEnum * DummyEnum * DummyEnum * DummyEnumThe $1.class
*   DummyEnum$2The $sign in.class Java files indicates the existence of an inner class, just like OutClass$InnerClassThe presence of these two files also supports the above statement of anonymous inner class initialization.Copy the code

import java.io.PrintStream;

public abstract class DummyEnum extends Enum { public static DummyEnum[] values() { return (DummyEnum[])$VALUES.clone(); }

public static DummyEnum valueOf(String s) { return (DummyEnum)Enum.valueOf(DummyEnum, s); } private DummyEnum(String s, int i) { super(s, i); } // abstract void dummyMethod(); Public static final DummyEnum DUMMY1; public static final DummyEnum DUMMY2; private static final DummyEnum $VALUES[]; Static {DUMMY1 = new DummyEnum("DUMMY1", 0) {public void dummyMethod() {system.out.println ("[1]: implements abstract method in enum class"); }}Copy the code

; DUMMY2 = new DummyEnum(“DUMMY2”, 1) { public void dummyMethod() { System.out.println(“[2]: implements abstract method in enum class”); }}; $VALUES = (new DummyEnum[] {DUMMY1, DUMMY2}); }}


### Normal enumeration classIn practice, enumeration classes usually take the form of a constructor with two arguments (int code, Sring MSG) that can be returned as a status code. The Enum class actually provides a protected constructor with two arguments. To avoid ambiguity, the enumeration class has three constructors. The private constructor now has five arguments instead of two, and internally still passes the first two arguments to the parent class via super, leaving the remaining three arguments to be the ones it really supplies. Conceivably, if the custom enumerated class provides only one argument, the resulting private constructor in the underlying code should have three arguments, the first two still passed to the parent class via super.Copy the code

public final class CustomEnum extends Enum { public static CustomEnum[] values() { return (CustomEnum[])$VALUES.clone(); }

public static CustomEnum valueOf(String s)  
{  
    return (CustomEnum)Enum.valueOf(CustomEnum, s);  
}  

private CustomEnum(String s, int i, int j, String s1, Object obj)  
{  
    super(s, i);  
    code = j;  
    msg = s1;  
    data = obj;  
}  

public static final CustomEnum FIRST;  
public static final CustomEnum SECOND;  
public static final CustomEnum THIRD;  
private int code;  
private String msg;  
private Object data;  
private static final CustomEnum $VALUES[];  

static   
{  
    FIRST = new CustomEnum("FIRST", 0, 10010, "first", Long.valueOf(100L));  
    SECOND = new CustomEnum("SECOND", 1, 10020, "second", "Foo");  
    THIRD = new CustomEnum("THIRD", 2, 10030, "third", new Object());  
    $VALUES = (new CustomEnum[] {  
        FIRST, SECOND, THIRD  
    });  
}  
Copy the code

}

! [by JAD decompiler I found many interesting code] (HTTP: / / https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/3/23/1710806395ac7e2f~tplv- T2oaga2asx-image.image) JAD decompression tool, no longer updated, and only supports JDK1.4, but does not affect its powerful function. Basic usage: jad xxx.class, which generates a direct readable xxx.jad file. ----- For conversion between primitive and wrapper types, xxxValue() and valueOf() are used to complete automatic unboxing. Using jad to decompile, you can see the process:Copy the code

public class Demo { public static void main(String[] args) { int x = new Integer(10); Integer y = x; // automatic packing}}

Decompiling results:Copy the code

public class Demo

{

public Demo(){}

public static void main(String args[]) { int i = (new Integer(10)).intValue(); // intValue() unboxing Integer Integer = integer.valueof (I); // valueOf() box}Copy the code

}

Foreach sugar ---------- Foreach sugar can be converted directly to array types when iterating overforCycle:Copy the code

Int [] arr = {1, 2, 3, 4, 5}; for(int item: arr) { System.out.println(item); }}

Int ai[] = {1, 2, 3, 4, 5}; int ai1[] = ai; int i = ai1.length; // convert to for loop for(int j = 0; j < i; j++) { int k = ai1[j]; System.out.println(k); }

Iterators are used to iterate over container classes:Copy the code

import java.io.PrintStream;

import java.util.*;

public class Demo { public Demo() {} public static void main(String args[]) { ArrayList arraylist = new ArrayList(); arraylist.add(Integer.valueOf(1)); arraylist.add(Integer.valueOf(2)); arraylist.add(Integer.valueOf(3)); Integer integer; // For (ListNode cur = head; cur ! = null; System.out.println(cur.val)){ // cur = cur.next; // } for(Iterator iterator = arraylist.iterator(); iterator.hasNext(); System.out.println(integer)) integer = (Integer)iterator.next(); }}

Arrays.asList(T...) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - familiar with Arrays. AsList () T... The asList() method cannot pass an array of primitive types. It must be wrapped as a wrapper, otherwise the size of the generated list is always 1:Copy the code

import java.util.*; public class Demo { public static void main(String[] args) { int[] arr1 = {1, 2, 3}; Integer[] arr2 = {1, 2, 3}; List lists1 = Arrays.asList(arr1); List lists2 = Arrays.asList(arr2); System.out.println(lists1.size()); // 1 System.out.println(lists2.size()); / / 3}}

From the decompilation result, we can explain why we return a List of size 1 when we pass in an array of primitive type:Copy the code

// Decomcompiled file import java.io.PrintStream; import java.util.Arrays; import java.util.List;

public class Demo

{

public Demo() {}

public static void main(String args[]) { int ai[] = { 1, 2, 3 }; Integer ainteger[] = {integer.valueof (1), integer.valueof (2), integer.valueof (3)}; Array.size () returns 1 list list = array.asList (new int[][] {ai}); // Array.size () returns 1 list list = array.asList (new int[][] {ai}); List list1 = Arrays.asList(ainteger); System.out.println(list.size()); System.out.println(list1.size()); }Copy the code

}

As you can see from the above results, passing in an array of primitive type is converted to a two-dimensional array, and the array is **new int[1][arr.length]**. Calling list.size() returns 1. Annotations - Classes, interfaces, enumerations, and annotations in Java can all be considered class types. Use jad to see what @interface is converted to:Copy the code

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)

public @interface Foo{

String[] value();

boolean bar();

}

Looking at the decomcompiled code, you can see that: * The custom Annotation class Foo is converted to interface Foo, and the inherited Annotation interface * Value () and bar() from the definition interface are converted to abstract methodsCopy the code

import java.lang.annotation.Annotation;

public interface Foo

extends Annotation

{

public abstract String[] value();

public abstract boolean bar();  
Copy the code

}

Annotations are usually used in conjunction with reflection, and since custom annotations are eventually converted to interfaces and attributes in annotations are converted to abstract methods in the interface, the corresponding abstract methods can be called from the interface instance after reflection:Copy the code

import java.util.Arrays;

@Foo(value={“sherman”, “decompiler”}, bar=true)

public class Demo{

public static void main(String[] args) {

Foo foo = Demo.class.getAnnotation(Foo.class);

System.out.println(Arrays.toString(foo.value())); // [sherman, decompiler]

System.out.println(foo.bar()); // true

}

}

Enumeration -- Enumeration classes are well understood by jad decompression.# # # empty enumerationDefine an empty enumeration class:Copy the code

public enum DummyEnum {

}

Using JAD decomcompiling to see the results: * The custom enumeration class is converted to final, and inherits Enum * that provides a private constructor for two arguments (name, odinal), and calls the constructor for the parent class. Note that there is a constructor even if no arguments are provided, where name is the name of the enumeration instance and odinal is the index number of the enumeration instance$VALUES** * provides two public static methods: the values() method passescloneThe () method returns to the interior$VALUESA shallow copy of. This method, combined with a private constructor, perfectly implements the singleton pattern. Consider whether the values() method functions like getInstance() in the singleton pattern: valueOf(String s) calls the parent Enum valueOf method and returns itCopy the code

public final class DummyEnum extends Enum

{

// The function is the same as the singleton getInstance() method

public static DummyEnum[] values()

{

return (DummyEnum[])VALUES[] = new DummyEnum[0];

}


### contains enumerations of abstract methodsEnumeration classes can also contain abstract methods, but the enumeration instance must be defined and the abstract method overridden immediately, as follows:Copy the code

public enum DummyEnum { DUMMY1 { public void dummyMethod() { System.out.println(“[1]: implements abstract method in enum class”); }},

DUMMY2 { public void dummyMethod() { System.out.println("[2]: implements abstract method in enum class"); }}; abstract void dummyMethod();Copy the code

}

* Final class becomes abstract class: It is easy to understand with the class nature of the abstract methods is more abstract class * two public static final DUMMY1, DUMMY2, the members of the two instance initialization process is on the static block of code, and the instance directly to rewrite the abstract methods in the process, is similar to the form of an anonymous inner class. * * * an array$VALUES[]** Are there any other changes to putting enumeration instances into the initialization? In the decomcompiled DummyEnum class, there are abstract methods, which enumeration instances override during initialization in static code blocks. In Java, abstract methods and abstract method overrides are placed in a single class and can only be done in inner class form. Therefore, the second point above should say that an achievement is initialized in an internal form. * DummyEnum * DummyEnum * DummyEnum * DummyEnum * DummyEnum * DummyEnum * DummyEnumThe $1.class
*   DummyEnum$2The $sign in.class Java files indicates the existence of an inner class, just like OutClass$InnerClassThe presence of these two files also supports the above statement of anonymous inner class initialization.Copy the code

import java.io.PrintStream;

public abstract class DummyEnum extends Enum { public static DummyEnum[] values() { return (DummyEnum[])$VALUES.clone(); }

public static DummyEnum valueOf(String s) { return (DummyEnum)Enum.valueOf(DummyEnum, s); } private DummyEnum(String s, int i) { super(s, i); } // abstract void dummyMethod(); Public static final DummyEnum DUMMY1; public static final DummyEnum DUMMY2; private static final DummyEnum $VALUES[]; Static {DUMMY1 = new DummyEnum("DUMMY1", 0) {public void dummyMethod() {system.out.println ("[1]: implements abstract method in enum class"); }}Copy the code

; DUMMY2 = new DummyEnum(“DUMMY2”, 1) { public void dummyMethod() { System.out.println(“[2]: implements abstract method in enum class”); }}; $VALUES = (new DummyEnum[] {DUMMY1, DUMMY2}); }}


### Normal enumeration classIn practice, enumeration classes usually take the form of a constructor with two arguments (int code, Sring MSG) that can be returned as a status code. The Enum class actually provides a protected constructor with two arguments. To avoid ambiguity, the enumeration class has three constructors. The private constructor now has five arguments instead of two, and internally still passes the first two arguments to the parent class via super, leaving the remaining three arguments to be the ones it really supplies. Conceivably, if the custom enumerated class provides only one argument, the resulting private constructor in the underlying code should have three arguments, the first two still passed to the parent class via super.Copy the code

public final class CustomEnum extends Enum { public static CustomEnum[] values() { return (CustomEnum[])$VALUES.clone(); }

public static CustomEnum valueOf(String s)  
{  
    return (CustomEnum)Enum.valueOf(CustomEnum, s);  
}  

private CustomEnum(String s, int i, int j, String s1, Object obj)  
{  
    super(s, i);  
    code = j;  
    msg = s1;  
    data = obj;  
}  

public static final CustomEnum FIRST;  
public static final CustomEnum SECOND;  
public static final CustomEnum THIRD;  
private int code;  
private String msg;  
private Object data;  
private static final CustomEnum $VALUES[];  

static   
{  
    FIRST = new CustomEnum("FIRST", 0, 10010, "first", Long.valueOf(100L));  
    SECOND = new CustomEnum("SECOND", 1, 10020, "second", "Foo");  
    THIRD = new CustomEnum("THIRD", 2, 10030, "third", new Object());  
    $VALUES = (new CustomEnum[] {  
        FIRST, SECOND, THIRD  
    });  
}  
Copy the code

}

! [by JAD decompiler I found many interesting code] (HTTP: / / https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/3/23/1710806395ac7e2f~tplv- T2oaga2asx-image.image) JAD decompression tool, no longer updated, and only supports JDK1.4, but does not affect its powerful function. Basic usage: jad xxx.class, which generates a direct readable xxx.jad file. ----- For conversion between primitive and wrapper types, xxxValue() and valueOf() are used to complete automatic unboxing. Using jad to decompile, you can see the process:Copy the code

public class Demo { public static void main(String[] args) { int x = new Integer(10); Integer y = x; // automatic packing}}

Decompiling results:Copy the code

public class Demo

{

public Demo(){}

public static void main(String args[]) { int i = (new Integer(10)).intValue(); // intValue() unboxing Integer Integer = integer.valueof (I); // valueOf() box}Copy the code

}

Foreach sugar ---------- Foreach sugar can be converted directly to array types when iterating overforCycle:Copy the code

Int [] arr = {1, 2, 3, 4, 5}; for(int item: arr) { System.out.println(item); }}

Int ai[] = {1, 2, 3, 4, 5}; int ai1[] = ai; int i = ai1.length; // convert to for loop for(int j = 0; j < i; j++) { int k = ai1[j]; System.out.println(k); }

Iterators are used to iterate over container classes:Copy the code

import java.io.PrintStream;

import java.util.*;

public class Demo { public Demo() {} public static void main(String args[]) { ArrayList arraylist = new ArrayList(); arraylist.add(Integer.valueOf(1)); arraylist.add(Integer.valueOf(2)); arraylist.add(Integer.valueOf(3)); Integer integer; // For (ListNode cur = head; cur ! = null; System.out.println(cur.val)){ // cur = cur.next; // } for(Iterator iterator = arraylist.iterator(); iterator.hasNext(); System.out.println(integer)) integer = (Integer)iterator.next(); }}

Arrays.asList(T...) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - familiar with Arrays. AsList () T... The asList() method cannot pass an array of primitive types. It must be wrapped as a wrapper, otherwise the size of the generated list is always 1:Copy the code

import java.util.*; public class Demo { public static void main(String[] args) { int[] arr1 = {1, 2, 3}; Integer[] arr2 = {1, 2, 3}; List lists1 = Arrays.asList(arr1); List lists2 = Arrays.asList(arr2); System.out.println(lists1.size()); // 1 System.out.println(lists2.size()); / / 3}}

From the decompilation result, we can explain why we return a List of size 1 when we pass in an array of primitive type:Copy the code

// Decomcompiled file import java.io.PrintStream; import java.util.Arrays; import java.util.List;

public class Demo

{

public Demo() {}

public static void main(String args[]) { int ai[] = { 1, 2, 3 }; Integer ainteger[] = {integer.valueof (1), integer.valueof (2), integer.valueof (3)}; Array.size () returns 1 list list = array.asList (new int[][] {ai}); // Array.size () returns 1 list list = array.asList (new int[][] {ai}); List list1 = Arrays.asList(ainteger); System.out.println(list.size()); System.out.println(list1.size()); }Copy the code

}

As you can see from the above results, passing in an array of primitive type is converted to a two-dimensional array, and the array is **new int[1][arr.length]**. Calling list.size() returns 1. Annotations - Classes, interfaces, enumerations, and annotations in Java can all be considered class types. Use jad to see what @interface is converted to:Copy the code

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)

public @interface Foo{

String[] value();

boolean bar();

}

Looking at the decomcompiled code, you can see that: * The custom Annotation class Foo is converted to interface Foo, and the inherited Annotation interface * Value () and bar() from the definition interface are converted to abstract methodsCopy the code

import java.lang.annotation.Annotation;

public interface Foo

extends Annotation

{

public abstract String[] value();

public abstract boolean bar();  
Copy the code

}

Annotations are usually used in conjunction with reflection, and since custom annotations are eventually converted to interfaces and attributes in annotations are converted to abstract methods in the interface, the corresponding abstract methods can be called from the interface instance after reflection:Copy the code

import java.util.Arrays;

@Foo(value={“sherman”, “decompiler”}, bar=true)

public class Demo{

public static void main(String[] args) {

Foo foo = Demo.class.getAnnotation(Foo.class);

System.out.println(Arrays.toString(foo.value())); // [sherman, decompiler]

System.out.println(foo.bar()); // true

}

}

Enumeration -- Enumeration classes are well understood by jad decompression.# # # empty enumerationDefine an empty enumeration class:Copy the code

public enum DummyEnum {

}

Using JAD decomcompiling to see the results: * The custom enumeration class is converted to final, and inherits Enum * that provides a private constructor for two arguments (name, odinal), and calls the constructor for the parent class. Note that there is a constructor even if no arguments are provided, where name is the name of the enumeration instance and odinal is the index number of the enumeration instance$VALUES** * provides two public static methods: the values() method passescloneThe () method returns to the interior$VALUESA shallow copy of. This method, combined with a private constructor, perfectly implements the singleton pattern. Consider whether the values() method functions like getInstance() in the singleton pattern: valueOf(String s) calls the parent Enum valueOf method and returns itCopy the code

public final class DummyEnum extends Enum

{

// The function is the same as the singleton getInstance() method

public static DummyEnum[] values()

{

return (DummyEnum[])VALUES[] = new DummyEnum[0];

}


### contains enumerations of abstract methodsEnumeration classes can also contain abstract methods, but the enumeration instance must be defined and the abstract method overridden immediately, as follows:Copy the code

public enum DummyEnum { DUMMY1 { public void dummyMethod() { System.out.println(“[1]: implements abstract method in enum class”); }},

DUMMY2 { public void dummyMethod() { System.out.println("[2]: implements abstract method in enum class"); }}; abstract void dummyMethod();Copy the code

}

* Final class becomes abstract class: It is easy to understand with the class nature of the abstract methods is more abstract class * two public static final DUMMY1, DUMMY2, the members of the two instance initialization process is on the static block of code, and the instance directly to rewrite the abstract methods in the process, is similar to the form of an anonymous inner class. * * * an array$VALUES[]** Are there any other changes to putting enumeration instances into the initialization? In the decomcompiled DummyEnum class, there are abstract methods, which enumeration instances override during initialization in static code blocks. In Java, abstract methods and abstract method overrides are placed in a single class and can only be done in inner class form. Therefore, the second point above should say that an achievement is initialized in an internal form. * DummyEnum * DummyEnum * DummyEnum * DummyEnum * DummyEnum * DummyEnum * DummyEnumThe $1.class
*   DummyEnum$2The $sign in.class Java files indicates the existence of an inner class, just like OutClass$InnerClassThe presence of these two files also supports the above statement of anonymous inner class initialization.Copy the code

import java.io.PrintStream;

public abstract class DummyEnum extends Enum { public static DummyEnum[] values() { return (DummyEnum[])$VALUES.clone(); }

public static DummyEnum valueOf(String s) { return (DummyEnum)Enum.valueOf(DummyEnum, s); } private DummyEnum(String s, int i) { super(s, i); } // abstract void dummyMethod(); Public static final DummyEnum DUMMY1; public static final DummyEnum DUMMY2; private static final DummyEnum $VALUES[]; Static {DUMMY1 = new DummyEnum("DUMMY1", 0) {public void dummyMethod() {system.out.println ("[1]: implements abstract method in enum class"); }}Copy the code

; DUMMY2 = new DummyEnum(“DUMMY2”, 1) { public void dummyMethod() { System.out.println(“[2]: implements abstract method in enum class”); }}; $VALUES = (new DummyEnum[] {DUMMY1, DUMMY2}); }}


### Normal enumeration classIn practice, enumeration classes usually take the form of a constructor with two arguments (int code, Sring MSG) that can be returned as a status code. The Enum class actually provides a protected constructor with two arguments. To avoid ambiguity, the enumeration class has three constructors. The private constructor now has five arguments instead of two, and internally still passes the first two arguments to the parent class via super, leaving the remaining three arguments to be the ones it really supplies. Conceivably, if the custom enumerated class provides only one argument, the resulting private constructor in the underlying code should have three arguments, the first two still passed to the parent class via super.Copy the code

public final class CustomEnum extends Enum { public static CustomEnum[] values() { return (CustomEnum[])$VALUES.clone(); }

public static CustomEnum valueOf(String s)  
{  
    return (CustomEnum)Enum.valueOf(CustomEnum, s);  
}  

private CustomEnum(String s, int i, int j, String s1, Object obj)  
{  
    super(s, i);  
    code = j;  
    msg = s1;  
    data = obj;  
}  

public static final CustomEnum FIRST;  
public static final CustomEnum SECOND;  
public static final CustomEnum THIRD;  
private int code;  
private String msg;  
private Object data;  
private static final CustomEnum $VALUES[];  

static   
{  
    FIRST = new CustomEnum("FIRST", 0, 10010, "first", Long.valueOf(100L));  
    SECOND = new CustomEnum("SECOND", 1, 10020, "second", "Foo");  
    THIRD = new CustomEnum("THIRD", 2, 10030, "third", new Object());  
    $VALUES = (new CustomEnum[] {  
        FIRST, SECOND, THIRD  
    });  
}  
Copy the code

}

Copy the code