Traps in expressions, expression traps

Source: Internet
Author: User

Traps in expressions, expression traps

Author: Chan Lou wangyue (http://www.cnblogs.com/yaoyinglong)

String traps

Common methods for creating objects in Java programs are as follows:

  • New;
  • Use the newInstance () method of the Class Object to call the constructor to create a Java object;
  • Deserialization;
  • Clone () method.

In addition, you can directly create Java objects by using the basic types, packaging classes, and strings of the basic classes. For example:

String str="hello world";Integer in=5;

For the number of characters in a Java program, JVM uses a string pool to protect them: When a string is used directly for the first time, JVM puts them into the string pool for caching. In general, the string object in the string buffer pool will not be garbage collected. When the program needs to use this string again, you do not need to create a new string, instead, direct the reference variable to an existing string in the string pool:

String str1="hello";String str2="hello";System.out.println(str1==str2);//-->true

Although String is a reference type. However, because the values of str1 and str2 are both direct quantities, they all point to the "hello" string in the JVM string pool. Therefore, true is output when str1 = str2.

Note:

You can also use a string connection expression to create a String object. If the value of this string connection expression can be determined during compilation, JVM calculates the value of this string variable during compilation and points it to the corresponding string in the string pool. However, if a variable or method is used in a string connection expression, the value of the string connection expression can only be determined at runtime, therefore, the value of the string variable cannot be determined during compilation. Therefore, the JVM string Pool cannot be used.

The output result is:

HoweverException: all variables in the String concatenation operation can be replaced with macros"

If "macro replacement" can be executed for all variables in the String concatenation operation, the value of the String concatenation expression can be determined during compilation by JVM, in the same way, the string variable points to the corresponding string in the JVM string pool.

String str="I love Java";final String str1="I love ";String str2=str1+"Java";System.out.println(str==str2);//-->true

Let's use the decompilation tool to see:

String str = "I love Java"; String str1 = "I love"; String str2 = "I love Java"; // macro replacement is executed here. During compilation, str1 is replaced with the corresponding value. This is because str1 is final and the final variable value does not change after initialization. Therefore, macro replacement can be executed. System. out. println (str = str2 );

Immutable string

String is unchangeable after creation. Only the reference of string variables can be changed, and the string object cannot be changed.

String str="I love Java";str="I love C#";

The second line of code does not change the "I love Java" String object to the "I love C #" String object, but changes the direction of str, point it to the "I love C #" String object, but the "I love Java" String object still exists in memory. However, the "I love Java" String object may never be used, but it will not be recycled by the garbage collector, it will always exist in the string pool ------> This is also a reason for Java Memory leakage. String comparison

Use "=" to compare whether the two strings reference the same string object. However, to compare whether two String sequences are the same, you must use the String equals method. The following is the source code of the String equals method:

public boolean equals(Object anObject) {        if (this == anObject) {            return true;        }        if (anObject instanceof String) {            String anotherString = (String) anObject;            int n = value.length;            if (n == anotherString.value.length) {                char v1[] = value;                char v2[] = anotherString.value;                int i = 0;                while (n-- != 0) {                    if (v1[i] != v2[i])                            return false;                    i++;                }                return true;            }        }        return false;    }

There are also compareTo series methods of String.

Expression type traps

The expression type is automatically upgraded.

When different data types appear in the expression, the result of the expression is based on the type of the highest-level operand in the table.

Trap of compound assignment operators

Such as: + =,-=, * = ...... And other compound assignment operators are implicitly included in type conversion.

As shown in, a = a + 5 has a compilation error. Because 5 is of the int type, the value of the entire expression is upgraded to int, a and short cannot perform automatic type conversion, so a compilation error occurs. The reason why a + = 5 does not show compilation errors is: let's look at how to handle the Java underlying layer:

Is it clear that the underlying layer silently performs implicit type conversion. How can this problem be solved? The type on the left of the equal sign is used as the type of the expression calculation result behind the equal sign. This can be dangerous: What if the calculation result range of the expression on the right of the equal sign is larger than that on the left of the equal sign can only be miserable, for example:

Therefore, we should be especially careful when using the composite assignment operator, especially:Multithreading trap

Do not use the Thread class to create a Thread.

Do not call the run method.

When synchronizing a code block, the program must explicitly specify a synchronization monitor for it. For non-static method Synchronization Methods, the synchronization Monitor of this method is this-the Java object that calls this method;For the static synchronization method, the synchronization Monitor of this method is not this but the current class itself..

public class Test implements Runnable{    static boolean staticFLag=true;    public static synchronized void test0(){        for(int i=0; i<100; i++){            System.out.println("test0:"+Thread.currentThread().getName()+" "+i);        }    }    public void test1(){        synchronized (this) {            for(int i=0; i<100; i++){                System.out.println("test1:"+Thread.currentThread().getName()+" "+i);            }        }    }    @Override    public void run() {        if(staticFLag){            staticFLag=false;            test0();        }else {            staticFLag=true;            test1();        }    }    public static void main(String[] args) throws InterruptedException {        Runnable runnable=new Test();        new Thread(runnable).start();        new Thread(runnable).start();    }}

The output is as follows:

Test0: Thread-0 0

Test1: Thread-1 0

Test0: Thread-0 1

Test1: Thread-1 1

Test0: Thread-0 2

Test1: Thread-1 2

Test0: Thread-0 3

Test1: Thread-1 3

......

We can see that because the two methods do not use the same synchronization monitor, they can be executed concurrently without affecting each other. But if we change it like this:

public class Test implements Runnable{    static boolean staticFLag=true;    public static synchronized void test0(){        for(int i=0; i<100; i++){            System.out.println("test0:"+Thread.currentThread().getName()+" "+i);        }    }    public void test1(){        synchronized (Test.class) {            for(int i=0; i<100; i++){                System.out.println("test1:"+Thread.currentThread().getName()+" "+i);            }        }    }    @Override    public void run() {        if(staticFLag){            staticFLag=false;            test0();        }else {            staticFLag=true;            test1();        }    }    public static void main(String[] args) throws InterruptedException {        Runnable runnable=new Test();        new Thread(runnable).start();        new Thread(runnable).start();    }}

Print:

Test0: Thread-0 0

Test0: Thread-0 1

Test0: Thread-0 2

......

Test0: Thread-0 98

Test0: Thread-0 99

Test1: Thread-1 0

Test1: Thread-1 1

......

Test1: Thread-1 99

We can see that when we display the synchronization monitor of the code block in the specified test1 method as Test. in class, because the test0 method and test1 method use the same synchronization monitor, so the lock of the synchronization monitor must be released in test0 method, test1 can be used.

Link: http://www.cnblogs.com/yaoyinglong/p/java%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%B8%AD%E7%9A%84%E9%99%B7%E9%98%B1.html

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.