当前位置:首页 > 体育 >

m+n等于1求m-n等于多少(m加n的绝对值等于多少)

来源:原点资讯(www.yd166.com)时间:2023-11-06 04:52:53作者:YD166手机阅读>>

了解 java 中 == 运算符和 equals() 方法之间的主要区别,并了解在 Java 编程中如何有效地使用它们进行对象比较。

public class Demo { public static void main(String args[]){ String a = "a" "b" 1; String b = "ab1"; System.out.println(a == b); } }

根据上面的代码,请看下列问题:

a和b在内存中的表示是什么?

编译时有什么优化策略吗?

“==”

在Java语言中,==用于比较两个内存单元的内容是否相同。

对于诸如 byte、boolean、short、char、int、long、float 和 double 等基本数据类型,比较的是它们的值。

对于引用类型,比较的是引用的值,可以将其视为对象的逻辑地址。

当 == 运算符应用于两个引用类型时,它会比较两个对象各自的内存地址是否相同。

也就是说,如果两个引用指向同一个对象,则返回true;否则,返回 false。

public class Demo { public static void main(String args[]){ List<String> a = null; List<String> b = null; System.out.println(a == b); } } 结果是:true“equals”

下面是Object类中equals()的源代码。

public boolean equals(Object obj) { return (this == obj); }

换句话说,如果没有重写 equals() 方法,并且相应类的父类也没有重写 equals() 方法,则 equals() 默认就是比较对象的地址。

equals()方法的存在是为了鼓励子类重写它,从而实现基于值的比较。

掌握了基础知识后,现在让我们解决文章开头提出的两个问题。

a和b在内存中的表示是什么?

由于 Java 的编译优化策略,a 和 b 都引用相同的内存位置。 我们可以使用JD-GUI反编译工具来检查反编译后的代码

public class Demo { public static void main(String[] args) { String a = "ab1"; String b = "ab1"; System.out.println(a == b); } } 结果是:true

到这里,结果应该就很清楚了。(==比较的内存地址) JVM在编译时对常量折叠进行了优化,因为常量折叠的结果是一个固定值,不需要运行时计算,所以通过这种方式进行优化。

不过,不要急于下结论。 JVM 只优化它能优化的部分。它并没有优化所有方面。

例如,前面提到的字符串连接。如果字符串的连接过程中有变量,意味着编译时不知道具体值,则 JVM 不会执行这种编译时合并。

如果你已经理解了上一段的意思,我们再来看另一个例子:

public class Demo { public static void main(String args[]){ String a = "a"; final String c ="a"; String b = a "b"; String d = c "b"; String e = getA() "b"; String compare = "ab"; System.out.println( b == compare); System.out.println( d == compare); System.out.println( e == compare); } private static String getA(){ return "a"; } } 结果是: false true false

根据我们之前的解释,很容易理解为什么 b == Compare 和 e == Compare 会产生错误结果。

这是因为 a 和 getA() 不是常量,所以并且没有对此进行编译时优化。相反,c是一个final的不可变的常量,所以进行了编译优化。

我们可以通过使用 JD-GUI 检查反编译代码来验证这一点:

import java.io.PrintStream; public class Demo { public static void main(String[] args) { String a = "a"; String c = "a"; String b = a "b"; String d = "ab"; String e = getA() "b"; String compare = "ab"; System.out.println(b == compare); System.out.println(d == compare); System.out.println(e == compare); } private static String getA() { return "a"; } }

从反编译的代码中,我们可以确认b和e没有经过JVM编译优化。

看到的是变量 d 已经被 JVM 优化了。 关键的区别在于变量 c 用 Final 修饰符修饰。 该声明对 c 的不可变性施加了严格的约束,并且由于 Final 意味着不可变性,因此编译器自然地知道结果也是不可变的。

字符串在内存里怎么存储?

m+n等于1求m-n等于多少,m加n的绝对值等于多少(1)

字符串对象内部使用字符数组进行存储。

现在,让我们看一下以下示例:

String m = "hello,world"; String n = "hello,world"; String u = new String(m); String v = new String("hello,world");

这段代码在内存中怎么分配?大致是这样的:

  • 它会分配一个长度为11的char数组,并在字符串池中创建一个由该char数组组成的字符串。然后,m 引用该字符串。
  • 使用n引用字符串池中的字符串,因此n和m引用同一个对象。
  • 生成一个新字符串,但其内部字符数组引用与 m 相同的数组。
  • 同样,创建了一个新字符串,但其内部字符数组引用了字符串池中的字符数组,即与u相同。

结论是m和n是同一个对象,而m、u和v是不同的对象,但它们都共享相同的字符数组。

使用equals()方法进行比较时,也会返回true。

我们可以使用反射来修改字符数组来验证效果。

public class Demo { public static void main(String args[]) throws NoSuchFieldException, IllegalAccessException { String m = "hello,world"; String n = "hello,world"; String u = new String(m); String v = new String("hello,world"); Field f = m.getClass().getDeclaredField("value"); f.setAccessible(true); char[] cs = (char[]) f.get(m); cs[0] = 'H'; String p = "Hello,world"; System.out.println(m.equals(p)); System.out.println(n.equals(p)); System.out.println(u.equals(p)); System.out.println(v.equals(p)); } } 结果是: true true true true

从上面的例子中,我们可以看到,通常说字符串是不可变的时,这意味着对字符串的引用是不可更改的,类似于其他final类。

虽然String类没有暴露它的value字段,但是仍然可以通过反射来修改它。

关于String中的intern()方法

public class Demo { public static void main(String args[]){ String a = "a"; String b = a "b"; String c = "ab"; String d = new String(b); System.out.println(b == c); System.out.println(c == d); System.out.println(c == d.intern()); System.out.println(b.intern() == d.intern()); } } 结果是: false false true true

String引用指向的对象存储在常量池中,保证具有相同值的字符串全局唯一。

如何确保这种全局唯一性?

当调用 intern() 方法时,JVM 使用 equals() 方法检查常量池中是否存在具有相等值的 String。

如果找到,则返回常量池中 String 对象的引用。如果没有找到匹配的字符串,它会创建一个具有相同值的新字符串,并在常量池中返回对此新字符串的引用。

只要两个字符串相同,对它们调用 intern() 就会产生对常量池中相应 String 的引用。 因此,在调用intern()之后,可以使用相等运算符来匹配两个字符串

,

栏目热文

求m和n的值是表示什么(m和n的值怎么计算)

求m和n的值是表示什么(m和n的值怎么计算)

中考几何压轴 114 几何与函数 面积计算的补偿技术这一系列,不限专题,解析系列经典几何题,提高几何分析解决问题能力。题...

2023-11-06 05:18:31查看全文 >>

n加1是收敛的还是发散的(-1的n次方是收敛还是发散)

n加1是收敛的还是发散的(-1的n次方是收敛还是发散)

我们前面已经证明了自然数的倒数之和是无穷发散的,是不收敛的,但它与In(1 n)之差却是一个常数,即著名的欧拉常数但是连...

2023-11-06 05:10:18查看全文 >>

n分之1的极限收敛吗(n 1分之n 1的极限怎么求)

n分之1的极限收敛吗(n 1分之n 1的极限怎么求)

数学分析研究的基础是极限。 事实上,牛顿已经给出了极限的想法,但如前面引用的那样,牛顿是用极限解释无穷小量。对于牛顿和...

2023-11-06 04:58:19查看全文 >>

n分之3是收敛还是发散(n加1的平方分之一收敛还是发散)

n分之3是收敛还是发散(n加1的平方分之一收敛还是发散)

都是正数居然会为负最近又有一个话题火了起来,从 1 到正无穷的正整数之和是否等于 -1/12 ?相信大部分人看到这里都会...

2023-11-06 05:21:35查看全文 >>

n乘n-3是什么公式(n+1中的n是怎么计算的举例说明)

n乘n-3是什么公式(n+1中的n是怎么计算的举例说明)

题目:给定1,2,3,…n,可以组成多少个积的形式,其中保持1,2,3,…n顺序不变,又能有多少个式子?题目很简单,我们...

2023-11-06 05:01:59查看全文 >>

含有1n的极限怎么求(含ln求极限的公式)

含有1n的极限怎么求(含ln求极限的公式)

我是小七,给大家分享电子元器件选型、电路项目等知识,干货满满。大家不要错过,建议收藏,错过就不一定找得到了,内容仅供参考...

2023-11-06 04:40:10查看全文 >>

n=1求m+n的值(求m n的值这种题型怎么做)

n=1求m+n的值(求m n的值这种题型怎么做)

妥妥学霸加分题,难倒了一大片学渣。已知m,n为正整数,欢迎学霸归来,解题且m² n²等于7381,求m n的值[来看...

2023-11-06 05:18:03查看全文 >>

为什么m+n等于1(m为什么有等于1的情况)

为什么m+n等于1(m为什么有等于1的情况)

项目施工进度管理422000第二章第二节内容概述本节内容的不算难,公共课的管理里面也有所涉及。几乎每年都在第二大题考查,...

2023-11-06 05:17:02查看全文 >>

文档排行