目录
- 1.自增自减(++i,i++,- -i,i- - )
- 2.==和equals
1.自增自减运算符
- ++i(- -i)先加减后运算
- i++(i- -)先运算后加减
- 这里拿加来举例(减亦是这样):区分i++,++i,i,三者区别
1
2
3
4
5
int i = 3;
int j = 4;
int c = i++ + ++j + i +j + --j;
System.out.println(c);
- 看到这种问题先不要着急算,先将他们的每一块的值算出来,然后根据他们运算符的优先级进行运算.
- i++整体是3 此时i=4, ++j整体是5,此时j=5,这就是上面提到的两种先加减后运算 ,和先运算后加减.
- 把上面的过程说一下, i++后i++=3,i=4, 然后++j,++j等于5,j=5, 然后 +4,+5, 然后- -j,- -j等于4.
- c = 3 + 5 + 4 + 5 + 4 = 21
2.==和equals的区别和用法
先看下面的代码说出他的运算结果
class A
{
//定义的属性
String name;
int age;
//空构造方法
public A(){}
//带参数的构造方法
public A(String name, int age)
{
this.name = name;
this.age = age;
}
//程序运行入口
public static void main(String[] args)
{
A a = new A("cheerui",19);
A b = new A("cheerui",19);
A c = new A("qwer",18);
A d = new A(new String("xiao"),19);
A e = new A(new String("xiao"),70 );
//判断a和b的年龄 1
System.out.println("a和b的年龄用==比较的结果是 "+(a.age == b.age)); //true
//判断a和c的年龄 2
System.out.println("a和c的年龄用==比较的结果是 "+(a.age == c.age)); //false
//对象a和对象b作比较,这个用的是equals 3
System.out.println("a和b用equals比较的结果是 "+(a.equals(b))); //false
//同样是对象a和b作比较 这个用的是== 4
System.out.println("a和b用==比较的结果是 "+(a == b)); //false
//对象a的名字和对象b的名字作比较 5
System.out.println("a和b的名字用equals比较的结果是"+(a.name.equals(b.name))); //true
//用==判断a和b的名字 6
System.out.println("a和b的名字用==比较的结果是 "+(a.name == b.name)); //true
//用==判断d和e的名字 7
System.out.println("d和e的名字用==比较的结果是 "+(d.name == e.name)); //false
//用equals判断d和e的名字 8
System.out.println("d和e的名字用equals比较的结果是"+(d.name.equals(e.name))); //true
}
输出结果是:
- 语句3 a和b是两个对象,用equals去比较他们,他们没有重写equals方法,所以他们的equals方法是Object的,Object的equals方法(见下图)也是用==来比较两个对象的,因为比较的是对象,是引用类型,所以比较的是地址,a和b是两个对象所以他们的地址不一样,结果就是false
- 这里也用到了多态, 他传入的是一个Object类型的参数,就是因为所有类都继承自Object类,父类引用指向子类在这里体现的淋漓尽致.
- 语句4 用==来比较a和b两个对象,就是在比较他们的地址,他们是两个对象,所以地址不一样,不管它里面存的东西是否一样,都是false.
- 语句5 用equals比较两个对象a和b的名字,为什么结果就是true了那,因为这里的equals方法不是Object的了,现在他是String类的equals方法(见下图),String类将父类中的equals方法重写,这时比较的就是他们的内容了.
- 这里也有多态
- 语句6 用==比较两个对象a和b的名字,首先判断比较的是什么类型的,发现name是String类型(String是一个类)的,那么比较的就是他们的地址,a和b是两个对象,那么他们中的引用类型的变量应该地址也是不一样的,结果应该为false.但是结果差强人意,下面会讲为什么是true.
- 语句7 同样用==比较两个对象d和e的名字,这次就和我们想的是一样的.(下面会说道,提前透露一下,这和String类型的变量初始化有关系).
- 语句8 用equals判断两个对象d和e的名字,这里就和5的原理是一样的,这里就不在赘述了.
String类型的两种初始化方式
- String s = new String(“cheerui”);
- String s1 = “cheerui”;
String s = new String(“cheerrui”)
- 这种通过new的初始化方式,就是和我们想的一样,会在堆中开辟一块空间,new两次就是开辟两块空间,所以7输出了false.
String s = “cheerui”
- 这种方式也是来初始化的,但是这种方式不会在堆中开辟空间,而是在静态区开辟空间,如果下一次在利用这种方式初始化的话,那么jvm首先会到静态区中看看有没有这个字符串,如果有就不会再次创建,而是直接把地址指向这个变量,这就是6中为什么是true的原因.
关于jvm的一些知识后面的更新会有
总结:
- ==比较的是变量中存储的东西,基本数据类型就判断他们具体的数值,引用类型就判断他们的地址.
- 引用类型之间的比较用equals来比较,String类型的equals方法jdk已经给重写,其他引用类型的就需要自己重写,如果不重写,就会调用Object的equals方法,你自己的类继承自Object方法,所以拥有Object的equals方法.