JAVA后端面试笔记

1.JAVA中==和equals的区别

区别:一个是运算符 ,一个是方法

==比较变量的值是否相同

①如果比较的对象是基本数据类型 ,则比较数值 是否相等

②如果比较的是引用数据类型 ,则比较的是对象的内存地址 是否相等

equals方法比较对象的内容是否相同

equals方法存在于Object类中,而Object类定义了equals方法

java 复制代码
  public boolean equals(Object obj) {
        return (this == obj);
    }

①如果类未重写equals方法,会调用Object父类中的equals方法(实际使用的也是==操作符)

②如果类重写了equals方法,则调用自己的equals方法(一般是比较对象的内容是否相等)

java 复制代码
@SpringBootApplication
public class SpringBootDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
        System.out.println("Hello World");
        User user1 = new User("18","520");
        User user2 = new User("18","520");
        System.out.println(user1.equals(user2));
    }
}

实体类

java 复制代码
@ApiModel(value = "用户实体类")
public class User {
    @ApiModelProperty(value = "用户姓名")
    public String userName;

    @ApiModelProperty(value = "用户密码")
    public String passWord;

    public User(String userName, String passWord) {
        this.userName = userName;
        this.passWord = passWord;
    }
}

比较两个对象是否相等,结果如下

java 复制代码
Hello World
false

虽然两个变量的内容是一样的,但由于User类没有重写equals方法,导致调用的equals是父类Object的方法,结果会返回false

重写equals可以使用到**@Data** ,相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode 这5个注解的合集, @EqualsAndHashCode默认是false,表示不调用父类的属性

对添加了@Data的注解的,刚开始测试的操作会返回true,因为user1和user2的内容是一样的

2.String,StringBuffer,StringBuilder区别

2.1 String

String数组是final修饰的,所以线程是安全的,但是不可变的

java 复制代码
@SpringBootApplication
public class SpringBootDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
        System.out.println("Hello World");

        String s1 = "Hello";
        String s2 = s1;

        System.out.println("修改前 s1 的身份哈希码:" + System.identityHashCode(s1));
        System.out.println("修改前 s2 的身份哈希码:" + System.identityHashCode(s2)); // 与 s1 相同

        s1 += " World";

        System.out.println("修改后 s1 的身份哈希码:" + System.identityHashCode(s1)); // 新值(新对象)
        System.out.println("修改后 s2 的身份哈希码:" + System.identityHashCode(s2)); // 旧值(原对象未变)

    }
}

结果如下,String是引用数据类型,刚开始s1和s2的指向的内容是一样的,所以修改前的身份哈希值是相等的,当s1拼接字符后引用地址发生变化,s1地址身份也发生了变化,但是s2不变

java 复制代码
Hello World
修改前 s1 的身份哈希码:1988584481
修改前 s2 的身份哈希码:1988584481
修改后 s1 的身份哈希码:205010614
修改后 s2 的身份哈希码:1988584481

2.2 StringBuffe

可变的,父类AbstractStringBuilder的数组是可变的

方法都用了synchronized,所以线程是安全的

2.3 StringBuilder

可变的,父类AbstractStringBuilder的数组是可变的

线程不安全,无锁,无final修饰符