我是靠谱客的博主 健忘毛豆,最近开发中收集的这篇文章主要介绍java字符串的赋值,java字符串赋值比较在写法上的区别,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一个简单的字符串比较,以下四种写法有什么区别呢?

写法一:

public class TestClass {

public void test() {

"str1".equals("str2");

}

public static void main(String[] args) {

new TestClass().test();

}

}

写法二:

public class TestClass {

public void test() {

String str = "str1";

str.equals("str2");

}

public static void main(String[] args) {

new TestClass().test();

}

}

写法三:

public class Constans {

public static final String str1 = "str1";

}

public class TestClass {

public void test() {

String str = Constans.str1;

str.equals("str2");

}

public static void main(String[] args) {

new TestClass().test();

}

}

写法四:

public class TestClass {

public void test() {

String str = "str1";

String st2 = "str2";

str.equals(st2);

}

public static void main(String[] args) {

new TestClass().test();

}

}

以上四种写法基本上一样,但如果我们非要抠一下区别呢,我们通过 javap -c -l TestClass.class 来看一下它们的区别。

写法一:

Compiled from "TestClass.java"

public class com.example.demo.compile.TestClass {

public com.example.demo.compile.TestClass();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

LineNumberTable:

line 8: 0

LocalVariableTable:

Start Length Slot Name Signature

0 5 0 this Lcom/example/demo/compile/TestClass;

public void test();

Code:

0: ldc #2 // String str1

2: ldc #3 // String str2

4: invokevirtual #4 // Method java/lang/String.equals:(Ljava/lang/Object;)Z

7: pop

8: return

LineNumberTable:

line 11: 0

line 12: 8

LocalVariableTable:

Start Length Slot Name Signature

0 9 0 this Lcom/example/demo/compile/TestClass;

public static void main(java.lang.String[]);

Code:

0: new #5 // class com/example/demo/compile/TestClass

3: dup

4: invokespecial #6 // Method "":()V

7: invokevirtual #7 // Method test:()V

10: return

LineNumberTable:

line 15: 0

line 16: 10

LocalVariableTable:

Start Length Slot Name Signature

0 11 0 args [Ljava/lang/String;

}

重点关注 test() 下的 Code 那一段。

写法二:

Compiled from "TestClass.java"

public class com.example.demo.compile.TestClass {

public com.example.demo.compile.TestClass();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

LineNumberTable:

line 8: 0

LocalVariableTable:

Start Length Slot Name Signature

0 5 0 this Lcom/example/demo/compile/TestClass;

public void test();

Code:

0: ldc #2 // String str1 将常量“str1”压入栈

2: astore_1 // 将栈中的“str1”pop出,赋值给str

3: aload_1 // 将str的引用值压入栈

4: ldc #3 // String str2

6: invokevirtual #4 // Method java/lang/String.equals:(Ljava/lang/Object;)Z

9: pop

10: return

LineNumberTable:

line 11: 0

line 12: 3

line 13: 10

LocalVariableTable:

Start Length Slot Name Signature

0 11 0 this Lcom/example/demo/compile/TestClass;

3 8 1 str Ljava/lang/String;

public static void main(java.lang.String[]);

Code:

0: new #5 // class com/example/demo/compile/TestClass

3: dup

4: invokespecial #6 // Method "":()V

7: invokevirtual #7 // Method test:()V

10: return

LineNumberTable:

line 16: 0

line 17: 10

LocalVariableTable:

Start Length Slot Name Signature

0 11 0 args [Ljava/lang/String;

}

可以看到,在 test 方法里, 写法二 比 写法一 多了对 str 局部变量的操作。

关于方法里的几个命令的作用,见下图:

写法三:

Compiled from "TestClass.java"

public class com.example.demo.compile.TestClass {

public com.example.demo.compile.TestClass();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

LineNumberTable:

line 8: 0

LocalVariableTable:

Start Length Slot Name Signature

0 5 0 this Lcom/example/demo/compile/TestClass;

public void test();

Code:

0: ldc #3 // String str1

2: astore_1

3: aload_1

4: ldc #4 // String str2

6: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z

9: pop

10: return

LineNumberTable:

line 11: 0

line 12: 3

line 13: 10

LocalVariableTable:

Start Length Slot Name Signature

0 11 0 this Lcom/example/demo/compile/TestClass;

3 8 1 str Ljava/lang/String;

public static void main(java.lang.String[]);

Code:

0: new #6 // class com/example/demo/compile/TestClass

3: dup

4: invokespecial #7 // Method "":()V

7: invokevirtual #8 // Method test:()V

10: return

LineNumberTable:

line 16: 0

line 17: 10

LocalVariableTable:

Start Length Slot Name Signature

0 11 0 args [Ljava/lang/String;

}

写法二 和 写法三 完全一样,这是为什么呢?

我们用反编译工具打开 写法三 的 class 文件。

从 class 文件反编译后了内容上看, 写法三 的 String str = Constans.str1 在编译后会被转成 String str = "str1" ,转之后跟 写法二 一样了。

java在编译的时候,会做一些性能上的优化,比如:为了减少运行时的栈调用,将 var = 常量字段 直接编译成 var = 常量字段的值 。

写法四:

Compiled from "TestClass.java"

public class com.example.demo.compile.TestClass {

public com.example.demo.compile.TestClass();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

LineNumberTable:

line 8: 0

LocalVariableTable:

Start Length Slot Name Signature

0 5 0 this Lcom/example/demo/compile/TestClass;

public void test();

Code:

0: ldc #3 // String str1

2: astore_1

3: ldc #4 // String str2

5: astore_2

6: aload_1

7: aload_2

8: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z

11: pop

12: return

LineNumberTable:

line 11: 0

line 12: 3

line 13: 6

line 14: 12

LocalVariableTable:

Start Length Slot Name Signature

0 13 0 this Lcom/example/demo/compile/TestClass;

3 10 1 str Ljava/lang/String;

6 7 2 st2 Ljava/lang/String;

public static void main(java.lang.String[]);

Code:

0: new #6 // class com/example/demo/compile/TestClass

3: dup

4: invokespecial #7 // Method "":()V

7: invokevirtual #8 // Method test:()V

10: return

LineNumberTable:

line 17: 0

line 18: 10

LocalVariableTable:

Start Length Slot Name Signature

0 11 0 args [Ljava/lang/String;

}

写法四 是在 写法二 基础上,又多了对 str2 局部变量的操作。

最后

以上就是健忘毛豆为你收集整理的java字符串的赋值,java字符串赋值比较在写法上的区别的全部内容,希望文章能够帮你解决java字符串的赋值,java字符串赋值比较在写法上的区别所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部