Java basic syntactic sugar [] in Java


Syntactic sugar (Syntactic Sugar), also known icing grammar, syntax refers to some kind of add in computer language, which grammar no effect on the function of language itself, it is only for the convenience of programmers to develop and improve development efficiency. To put it plainly, syntactic sugar is a package of existing grammars.

But in fact, Java virtual machine does not support the syntax sugar. These syntactic sugar at compile time will be reduced to simple basic grammatical structure, this process is syntactic sugar solution. So the real support of syntactic sugar is Java compiler.


Syntactic sugar in Java

  • String and enumeration switch support
  • Generics
  • Automatic boxing and unboxing
  • Method vararg
  • enumerate
  • Inner classes
  • Conditional compilation
  • Affirmation
  • Numeric literals
  • for-each
  • try-with-resource
  • Lambda expressions
  • String + character.

switch support for String and enumeration class

In fact, almost switch on support for the principle of enumeration and String. switch can support native support for integer comparison type. If you switch back type String, the compiler will convert the String hashCode value, so the comparison is actually hashCode value of String. If the switch is behind the Enum, the compiler will convert the subscript defined for this enumeration (ordinal). In fact, the last is the type integer comparison. Below Stirng give Liezi.

Source

public class switchDemoString {
    public static void main(String[] args) {
        String str = "world";
        switch (str) {
            case "hello":
                System.out.println("hello");
                break;
            case "world":
                System.out.println("world");
                break;
            default:
                break;
        }
    }
}

After the anti-compiled code

public class switchDemoString
{
    public switchDemoString()
    {
    }
    public static void main(String args[])
    {
        String str = "world";
        String s;
        switch((s = str).hashCode())
        {
        default:
            break;
        case 99162322:
            if(s.equals("hello"))
                System.out.println("hello");
            break;
        case 113318802:
            if(s.equals("world"))
                System.out.println("world");
            break;
        }
    }
}

Decompile can be found, a switch is actually a hash value, and then by using the equals method compares a security check, the check is necessary because the hash collision may occur. Thus its performance is not as good for enumeration using pure switch or an integer constant.

Support for generics

In JDK1.5, Java language introduces a generic mechanism. However, this generic type by erasing mechanism is achieved, i.e. the generic Java source code is only valid in the (source code phase provides type checking), casts automatically with the compiled bytecode instead. In other words, Java language is actually a generic mechanism syntactic sugar, compared with compared with C ++, C #, its generic implementation it is not so elegant.

/**
* 在源代码中存在泛型
*/
public static void main(String[] args) {
    Map<String,String> map = new HashMap<String,String>();
    map.put("hello","你好");
    String hello = map.get("hello");
    System.out.println(hello);
}

Compiled Code

public static void main(String[] args) {
    HashMap map = new HashMap(); //类型擦除
    map.put("hello", "你好");
    String hello = (String)map.get("hello");//强制转换
    System.out.println(hello);
}

By the decompiled code above we find that the virtual machine is not in fact generic, only ordinary classes and ordinary methods, all of a generic class type parameters will be erased at compile time, a generic class and not have their own unique class class object.

Package type automatic boxing and unboxing

We know that between eight in Java basic types and corresponding packaging type can be assigned to each other (a process called packing, unpacking process). In fact, the principle behind this is that the compiler is optimized. Code like the following, will be assigned to the basic types of packaging actually calls the wrapper class valueOf () method creates a wrapper class and then be assigned to the basic types. The wrapper class assigned to the basic type is called xxxValue wrapper class () method to get the basic data types and then assigned.

public static void main(String[] args) {
    Integer a = 1;
    int b = 2;
    int c = a + b;
    System.out.println(c);
}

Compiled Code

public static void main(String[] args) {
    Integer a = Integer.valueOf(1); // 自动装箱
    byte b = 2;
    int c = a.intValue() + b;//自动拆箱
    System.out.println(c);
}

The method of variable length parameter

Variable length parameter characteristic is introduced in the JDK1.5, variable length parameters using two conditions, one variable length parameter that part of the same type, and second variable length rearmost method parameter must be in the argument list. Vararg same syntactic sugar in Java, which is realized inside the compiler to compile the source code when converted into variable length parameter section Java array.

enumerate

Java classes used in the definition of class, the class definition of the enumeration using enum. In Java bytecode structure, in fact, not enumerated types, enumerated types just syntactic sugar, after the completion compiled into a regular class at compile, is modified by Class. This class inherits java.lang.Enum, modified and final keywords.

public enum Fruit {
    APPLE,ORINGE
}   

The Fruit of class file decompile

//继承java.lang.Enum并声明为final
public final class Fruit extends Enum
{

    public static Fruit[] values()
    {
        return (Fruit[])$VALUES.clone();
    }

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

    private Fruit(String s, int i)
    {
        super(s, i);
    }
    //枚举类型常量
    public static final Fruit APPLE;
    public static final Fruit ORANGE;
    private static final Fruit $VALUES[];//使用数组进行维护

    static
    {
        APPLE = new Fruit("APPLE", 0);
        ORANGE = new Fruit("ORANGE", 1);
        $VALUES = (new Fruit[] {
            APPLE, ORANGE
        });
    }
}

Through the above decompiled code, we can know when we use enmu to define when an enumerated type, the compiler will automatically help us create a final type of class inheritance Enum class, enumerated types can not be inherited.

Inner classes

The reason why the Java language into the interior of the class, because there are times when a class just want to be useful in a class, we do not want it to be used in another place. The reason why the inner class is syntactic sugar, because it is only a concept at compile time, once compiled, the compiler generates a separate class file for the inner class, called the outer $ innter.class.

public class Outer {
    class Inner{
    }
}

After use javac compiler generates class files Outer.class and two Outer $ Inner.class, wherein the content Outer $ Inner.class follows:

class Outer$Inner {
    Outer$Inner(Outer var1) {
        this.this$0 = var1;
    }
}

Conditional compilation

In general, source code compilation to participate in all rows. But sometimes hope is only part of it compiled under certain conditions, which specifies the conditions for the part of the compiler, which is "conditional compilation" (conditional compile).

Conditional compilation in Java is achieved by optimizing compiler principles:

  • If the if condition is false, then ignore this if statement at compile time.
  • Ignore unused variables.
public class ConditionalCompilation02
{
    public static void main(String[] args) {
        if(CompilationConfig.DEBUG_MODE)
        {
            System.out.println("[DEBUG MODE]You can print sth");
        }
        else
        {
            System.out.println("[RELEASE MODE]You can print sth");
        }
    }
}

Therefore, the conditional compilation Java syntax, is implemented as a constant if statement by judging conditions. The true and false if the determination condition, the compiler directly to the branch code blocks to eliminate false. By compiling the manner of conditions, must be achieved in vivo, but not in a positive conditional compilation entire Java class structure or class attributes.

Affirmation

In Java, assert keyword from JAVA SE 1.4 is introduced, in order to avoid and older versions of Java code uses the assert keyword causes an error, Java is not activated by default assertion checking (this time, all in the implementation of the assert statements will be ignored!).

To open assertion checking, it is necessary to open or switch -enableassertions -ea.

In fact, the assertion that if the underlying implementation language, if the result of the assertion is true, do nothing, the program continues, if the result of the assertion is false, the program throws AssertError to interrupt the execution of the program.

Numeric literals

Supported in Java Numeric literals of the form

  • Decimal: Default
  • Octal: Before adding the integer number 0 to represent
  • Hex: add "0x" or "0X" before integer
  • Binary (newly added): integer plus before "0b" or "0B"

In JDK7 In addition, the numeric literal, integer or floating-point either, allow the insertion between any number of underlined numbers. These underscore will not affect the value of literal, the purpose is easy to read. such as:

  • 1_500_000
  • 5_6.3_4
  • 89_3___1

Underline only appear in digital intermediate, front and rear must be a number. So "_100", "0b_101" is not legitimate, not compile. Such restrictions motivation is that we can reduce the complexity of implementation. With this limitation, digital intermediate underscore the Java compiler simply scanning the source code will be found when directly delete it. If you do not add this restriction, the compiler needs to be parsed in order to make judgments. For example: _100, may be an integer literal 100, it may be a variable name. This requires the implementation of compiler to make more complex changes.

for-each

Object enhanced for loop is either an array or implements Iterable interface. The syntactic sugar is mainly used to traverse the array or set, it can not change the size of a collection cycle. Enhanced for loop mainly to make the code more concise, the principle behind it is that the compiler will enhance converted into ordinary for loop for loop.

public static void main(String[] args) {
    String[] params = new String[]{"hello","world"};
    //增强for循环对象为数组
    for(String str : params){
        System.out.println(str);
    }

    List<String> lists = Arrays.asList("hello","world");
    //增强for循环对象实现Iterable接口
    for(String str : lists){
        System.out.println(str);
    }
}

After the compiler to compile the code

public static void main(String[] args) {
   String[] params = new String[]{"hello", "world"};
   String[] lists = params;
   int var3 = params.length;
   //数组形式的增强for退化为普通for
   for(int str = 0; str < var3; ++str) {
       String str1 = lists[str];
       System.out.println(str1);
   }

   List var6 = Arrays.asList(new String[]{"hello", "world"});
   Iterator var7 = var6.iterator();
   //实现Iterable接口的增强for使用iterator接口进行遍历
   while(var7.hasNext()) {
       String var8 = (String)var7.next();
       System.out.println(var8);
   }

}

try-with-resource

When an object handle external resources to achieve the AutoCloseable interface in JDK7 you can use try-with-resource more elegant syntax shut resources, eliminate plate code.

public static void main(String[] args) {
    try (FileInputStream inputStream = new FileInputStream(new File("test"))) {
        System.out.println(inputStream.read());
    } catch (IOException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
}

It will create the object's handle external resources in a try keywords in brackets after it, when the try-catch block is finished, Java will ensure that external resources close method is called. Code is not the moment many simple! try-with-resource JVM is not new in the virtual machine, but the JDK implementation of a syntactic sugar, when you decompile the code above will find that, in fact, JVM virtual machine is concerned, it is still seen before writing:

public static void main(String[] args) {
    try {
        FileInputStream inputStream = new FileInputStream(new File("test"));
        Throwable var2 = null;
        try {
            System.out.println(inputStream.read());
        } catch (Throwable var12) {
            var2 = var12;
            throw var12;
        } finally {
            if (inputStream != null) {
                if (var2 != null) {
                    try {
                        inputStream.close();
                    } catch (Throwable var11) {
                        var2.addSuppressed(var11);
                    }
                } else {
                    inputStream.close();
                }
            }
        }

    } catch (IOException var14) {
        throw new RuntimeException(var14.getMessage(), var14);
    }
}

In fact, very simple principle behind those closed resources we did not do the operation, the compiler will help us to do.

Lambda expressions

Lambda expressions although looked very advanced, but in fact the essence of Lambda expressions just a "syntactic sugar", inferred by the compiler package and help you convert conventional code , so you can use less code to achieve the same function . I suggest not to use, and because of this some very high-level hackers write the code as simple and difficult to understand, difficult to debug, maintenance personnel want to BS-ing .

lambda expressions allow you to replace the function of the interface by the expression. Lambda expressions also enhance the collection of the library. Java SE 8 adds two data packets to a set of batch operation: java.util.function java.util.stream packages and packages. Stream (stream) just as iterators (iterator), but not without a lot of extra features. Overall, lambda expressions, and stream from the Java language is the biggest change since added generics (Generics) and notes (annotation).

Lambda expression syntax

基本语法:
(parameters) -> expression
或
(parameters) ->{ statements; }

Lambda expressions are a few simple Liezi

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)

Examples of substantially Lambda (implement function interface)

String[] atp = {"Rafael Nadal", "Novak Djokovic",
                "Stanislas Wawrinka",
                "David Ferrer", "Roger Federer",
                "Andy Murray", "Tomas Berdych",
                "Juan Martin Del Potro"};

        List<String> players =  Arrays.asList(atp);

        //实现功能接口
        players.forEach((String player) ->{
            System.out.println(player);
        });
        Runnable runnable = () -> {
            System.out.println("l am a new thread...");
        };
        new Thread(runnable).start();   

Use Lambdas ordered set

players.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
Comparator<String> comparator = (String o1,String o2) ->{return o1.compareTo(o2);};
players.sort(comparator);

Use Lambdas and Streams

Stream is a collection of packaging, often used in conjunction with lambda. Use lambdas can support a number of operations, such as map, filter, limit, sorted, count, min, max, sum, collect the like. Similarly, Stream computing using lazy, they do not really read all the data, someone like getFirst () method will end this chain syntax.

Support string of numbers +

String s=null;
s=s+"abc";
System.out.println(s);

The above code output?

String concatenation principle: running, two strings str1, str2 stitching first calls String.valueOf (obj), the Obj is str1, achieved String.valueOf (Obj) is the return obj == null "? null ": obj.toString (), and then generates StringBuilder, StringBuilder (str1) constructor method call to initialize the StringBuilder, length str1.length () + 16, and call append (str1)! Next call StringBuilder.append (str2), the second string concatenation in, then call StringBuilder.toString returns the result!

So the answer is: StringBuilder ( "null") append ( "abc") toString (); // nullabc..

reference

https://www.cnblogs.com/wanshiming/p/7685684.html
https://www.cnblogs.com/franson-2016/p/5593080.html
https://www.jb51.net/article/138519.htm

Guess you like

Origin www.cnblogs.com/54chensongxia/p/11665843.html