理解Java最重要的8张图

一图胜千言,下面图解均来自Program Creek 网站的Java教程

字符串的不变性

  1. 定义字符串
String s = "abcd";

s持有字符串abcd的引用
这里写图片描述
2. 用一个字符串变量赋值另一个字符串变量

String s2 = s;

s2和s持有同一个对象的引用
这里写图片描述
3. 合并字符串

s = s.concat("ef");

这里写图片描述

总结

一旦在堆内存中创建了字符串,字符串本身是不能改变的,如果要改变通过返回新的字符串对象实现。因此为了避免产生更多的临时变量,消耗垃圾回收机制资源,改变String,尽量使用StringBuilder和StringBuffer类代替String。

Java equals()方法和hashCode()方法的联系

public boolean equals(Object obj)
public int hashCode()

这两个方法是在Java super class “java.lang.Object”中定义的重要方法,

  • 如果两个对象相等 那么她们hashCode一定相等
  • 如果两个对象hashCode相等,她们两个对象不一定相等
    这里写图片描述
    ##一个常见的错误
import java.util.HashMap;

public class Apple {
    private String color;

    public Apple(String color) {
        this.color = color;
    }

    public boolean equals(Object obj) {
        if(obj==null) return false;
        if (!(obj instanceof Apple))
            return false;   
        if (obj == this)
            return true;
        return this.color.equals(((Apple) obj).color);
    }

    public static void main(String[] args) {
        Apple a1 = new Apple("green");
        Apple a2 = new Apple("red");

        //hashMap stores apple type and its quantity
        HashMap<Apple, Integer> m = new HashMap<Apple, Integer>();
        m.put(a1, 10);
        m.put(a2, 20);
        System.out.println(m.get(new Apple("green")));
    }
}

对象green Apple明明已经被加入到Map中,但是检索Map的时候查找green Apple对象却返回空

问题由于hashCode()引起

因为Apple对象没有实现hashCode方法,在Map中为了去查找一个对象比线性查找更快,通过两个验证的方式查找,如果两个对象的hashCode不相等,就不用再执行它们的equals方法了。
解决上面问题只需要实现他的hashCode方法即可

public int hashCode(){
    return this.color.hashCode();   
}

Java异常类的继承关系

Java中的异常分为可检测异常和不可预知异常,她们的关系在下表中
红色的为受检查异常,任何受检测异常可以在方法体或者方法定义中抛出。必须在编译期完成。绿色的是不可测异常
这里写图片描述

Collection和Collections

  1. 这是两个完全不同的东西。Collection是Collection接口继承关系中的根接口,而Collections是一个包含很多操作集合元素静态方法的类。
    这里写图片描述
  2. Collection的继承关系
    这里写图片描述
  3. Map的继承关系
    这里写图片描述

Java同步机制

这里写图片描述

别名

别名意味着可以为同一块内存区域给予不同的名称,这些名称可以是不同的类型。
这里写图片描述

B[] b = new B[10];
A[] a = b;

a[0] =  new A();
b[0].methodParent();

a、b都指向内存区域,到运行时再确定实际要调用的是谁

class A {
    public void methodParent() {
        System.out.println("method in Parent");
    }
}

class B extends A {
    public void methodParent() {
        System.out.println("override method in Child");
    }

    public void methodChild() {
        System.out.println("method in Child");
    }
}

public class Main {

    public static void main(String[] args) {

        B[] b = new B[10];
        A[] a = b;

        a[0] =  new A();
        b[0].methodParent();
    }
}

这段代码如果运行将会报错

Exception in thread "main" java.lang.ArrayStoreException: aliasingtest.A
    at aliasingtest.Main.main(Main.java:26)

需要修改

B[] b = new B[10];
A[] a = b;

a[0] =  new B();
b[0].methodParent();

因为B[] b = new B[10];已经定义了数据类型为B,Java
是强类型语言

堆与栈

class A {
    int x;
    int y;
}

...

public void m1() {
    int i = 0;
    m2();
}

public void m2() {
    A a = new A();
}

对应的堆栈存储图为
这里写图片描述

Java运行时数据区域

下图显示了整个JVM运行时数据区。
这里写图片描述
各个线程栈区数据不共享,堆区、方法区、运行时常量区数据共享。
这里写图片描述
栈数据包括
局部变量数据组、操作栈、常量池数据引用
这里写图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值