------------------------------------------------------------------------------
1、==和equals的区别
1、== :
基本数据类型:比较值是否相等,
引用数据类型:比较引用的地址值是否相等,而非值是否相等;
2、equals:
如果在Object类中,仍然用的是“ == ”进行比较,与“ == ”效果一样
如果在String、Date、File等类中,因为都重写了equals方法,所以比较具体的值是否相等
代码示例:
package com.zhang.test02;
public class Test01 {
public static void main(String[] args) {
System.out.println("++++++++基本数据类型++++++++");
int a = 10;
int b = 10;
System.out.println(a == b);//true
System.out.println("++++++++引用数据类型++++++++");
String str1 = new String("aaa");
String str2 = new String("aaa");
//false 比较地址值是否相等,str1和str2引用不同的堆空间的地址
System.out.println(str1 == str2);
//true String重写equals方法,比较值是否相等,
System.out.println(str1.equals(str2));
Person person1 = new Person(100);
Person person2 = new Person(100);
//false 比较地址值是否相等,str1和str2引用不同的堆空间的地址
System.out.println(person1 == person2);
//false 使用Object类中的equals方法,与“ == ”效果一样
System.out.println(person1.equals(person2));
}
}
class Person{
private int id;
public Person(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
'}';
}
}
输出结果
++++++++基本数据类型++++++++
true
++++++++引用数据类型++++++++
false
true
false
false
2、String为什么可以直接赋值
String为什么可以直接赋值:例如String str = “abc”;?
因为String类在Java中用的比较多,所以String在直接赋值时,将字符串直接存放在字符串常量池中
1、String直接赋值的值都放在字符串常量池中;
2、实例化出来的字符串也会在常量池中保存一份;例如:String str = new String(“aaa”);此时,会在堆内存中保存一份“aaa”,如果字符串常量池中没有“aaa”,则会在字符串常量池中也保存一份“aaa”,不过str引用的是堆内存“aaa”的地址
3、相同的值在字符串常量池中只会存在一份,节省空间
例如:
String str1 = “abc”;
String str2 = “abc”;
String str3 = “abc”;
String str4 = new String(“abc”);
上述的“abc”在字符串常量池中只会存在一份,所以str1、str2、str3都是引用字符串常量池中这一份“abc“的地址值,当然str4还是引用的自己堆内存的地址;
针对1、2、3进行代码说明:
public class Test01 {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
//true 比较地址,地址相同,同为字符串常量池的“abc”的地址
System.out.println(str1 == str2);
//false 比较地址,str3为堆内存的地址,
System.out.println(str1 == str3);
//true 比较具体的值
System.out.println(str1.equals(str3));
}
}
输出结果
true
false
true
3、static关键字
static可以用来修饰 属性、方法、代码块、内部类
3.1、static修饰属性
1、被static修饰的属性,归类所有,会随着类的加载而加载,所以静态变量的加载要早于对象创建;
2、由于类只加载一次,所以静态变量在内存中也只有一份,存放在方法区的静态域中
3、static修饰属性,那么被修饰的变量便为静态变量,多个对象共享同一个静态变量
代码示例:
public class Test01 {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "小七";
Person p2 = new Person();
//输出p2的值为:“小七” 给p1对象的name赋值后,p2对象的name值也为“小七”
System.out.println(p2.name);
Person p3 = new Person();
//p3对象修改name值,p1对象的name值也随之改变
p3.name = "新小七";
System.out.println(p1.name);
//静态变量可直接通过类名.方法名进行调用
Person.id = 110;
System.out.println(Person.id);
}
}
class Person{
//static修饰属性
public static int id;
public static String name;
}
输出结果
小七
新小七
110
3.2、static修饰方法
1、被static修饰的方法,会随着类的加载而加载,要早于对象创建,所以静态方法中不能直接调用非静态方法;
2、静态方法的调用是:”类名.方法名“;
2、注意点:静态方法中不能用this和super关键字
代码示例:
public class Test02 {
public static void main(String[] args) {
XiaoQi.test01();
XiaoQi xiaoQi = new XiaoQi();
xiaoQi.test02();
}
}
class XiaoQi{
//静态方法
public static void test01(){
//报错,不能直接调用非静态方法
//test02();
System.out.println("静态方法01");
}
//非静态方法
public void test02(){
System.out.println("非静态方法02");
test03();
}
//非静态方法
public void test03(){
System.out.println("非静态方法03");
}
}
输出结果:
静态方法01
非静态方法02
非静态方法03
4、final
final可以用来修饰:类、方法、变量
final修饰类:表示此类不可被继承;
final修饰方法:表示此方法不可被重写;
final修饰变量:表示此变量不可变,可看作一个常量,赋值方式有:直接赋值、代码块赋值、构造器赋值;
代码示例:
public class Test02 {
public static void main(String[] args) {
XiaoQi xiaoQi = new XiaoQi(300);
System.out.println(xiaoQi.a);
System.out.println(xiaoQi.b);
System.out.println(xiaoQi.c);
}
}
class XiaoQi{
final int a = 100;
final int b;
{
b = 200;
}
final int c;
public XiaoQi(int c){
this.c = c;
}
}
输出结果:
100
200
300