整理零碎的Java语法

整理零碎的Java语法

今天阿清想和大家分享一些面试或笔试常考的Java语法知识。

都是血与泪的教训>_<

我们直接开始!



01


执行顺序


当构造一个类时,若这个类既有父类,类中还有static代码块与普通代码块,此时执行顺序如下:

父类static代码块->子类static代码块->父类普通代码块->父类构造函数->子类普通代码块->子类构造函数

可看如下代码:

public class Father {
    private int fatherA = 0;

    static {
            System.out.println("Father-static-before 父类在构造函数之前的的代码块");
    }

    public Father (int fatherA) {
        System.out.println("父类构造函数");
        this.fatherA = fatherA;
    }

    {
        System.out.println("父类普通代码块!");
    }

    static {
        System.out.println("Father-static-after 父类在构造函数之后的的代码块");
    }
}
public class Son extends Father {
    private int sonA;

    static {
        System.out.println("son-static-before 子类在构造函数之前的的代码块");
    }

    public Son(int fatherA, int sonA) {
        super(fatherA);
        this.sonA = sonA;
        System.out.println("子类构造函数");

    }

    {
        System.out.println("子类普通代码块!");
    }

    static {
        System.out.println("son-static-after 子类在构造函数之后的的代码块");
    }
}
public class TestMain {
    public static void main(String[] args) {
        int fatherA = 0;
        int sonA = 1;
        Father f = new Son(fatherA, sonA);
    }
}
/** 控制台输出如下:
Father-static-before 父类在构造函数之前的的代码块
Father-static-after 父类在构造函数之后的的代码块
son-static-before 子类在构造函数之前的的代码块
son-static-after 子类在构造函数之后的的代码块
父类普通代码块!
父类构造函数
子类普通代码块!
子类构造函数
**/




02


基本类型与包装类型的比较


针对这个话题,面试与笔试经常考的是Integer与int这两种类型,有三种情况:

①Integer与int比较,②int与int比较,③Integer与Integer比较。

结论如下:

1、当使用==判断时,

①与②都是用取值去判断,若取值相等,则为true,  否则为false。

针对③,当取值在区间[-128, 127](左闭右闭区间)时且取值相等,则为ture。

否则,即使取值相等,也不一定为true。

2、当使用equals判断时,若取值相等,则为true,否则为false。

为什么当两个Integer对象取值在区间[-128, 127](左闭右闭区间)时且取值相等时,使用==判断这两个Integer对象结果都为true?

首先,使用==对两个对象引用进行判断时,判断的是两个对象是否为同一个对象。

而使用equals方法判断时,则是依照每个对象的equals方法的逻辑进行判断的,因此当使用 == 对两个对象引用进行判断返回true,则说明返回的是同一个对象。

在Integer的源码中设计了一个IntegerCache类,当取值属于区间[-128, 127]时,Integer会调用IntegerCache类构造的对象。

因此,只要取值属于区间[-128, 127],不管声明多少个Integer对象,其实都是引用了IntegerCache的对象,

而当使用==判断两个对象时,我们判断的是这两个对象是不是同一个对象,因此结果总为true。

顺带提一嘴:

每个基本数据类型都对应了相应的包装器。

自动装箱:自动将基本数据类型,转化为包装器类型,调用的是包装器的valueOf方法。

自动拆箱:自动将包装器类型转化为基本数据类型,调用的是包装器的xxxValue()方法。其中xxx代表包装器对应的基本类型。

Integer类型通过valueOf创建对象的时候,如果数值在[-128,127]之间,会调用IntegerCache.cache中已经存在的对象的引用,否则创建一个新的对象。

除了 Double、Float对象,其他的包装类型的valueOf方法与Integer类型实现的相似。

大家可以试试如下代码:

public static void main(String[] args) {
        int fatherA = 0;
        int sonA = 1;

        Integer a = 128;
        int b = 128;
        Integer c = 128;
        int t = 128;
        Integer e = 127;
        Integer k = 127;
        System.out.println(t == a);  // true
        System.out.println(a == b);  // true
        System.out.println(a == c);  // false
        System.out.println(a.equals(c));  //true
        System.out.println(e == k);  //true 
        System.out.println(e.equals(k));  //true
        System.out.println(a.equals(b));  //true
        System.out.println(c.equals(t));  //true
}



03


继承中的相同


1、若父类与子类中的有一个方法的方法名相同,且方法的函数签名也相同,此时子类的对象调用这个方法时,会调用子类的方法,不会调用父类的方法。

2、若父类与子类中的有一个成员变量的名字相同,此时子类在调用这个变量时,会调用子类的变量,不会调用父类的变量。

可参考如下代码:

public class Father {
    private int fatherA = 0;
 private int A = 0;
    
    public Father (int fatherA) {
        this.fatherA = fatherA;
    }

    public void sameNameMethod() {
        System.out.println("父类中调用sameNameMethod方法");
    }
 
    public int getA() {
        return this.A;
    }
    
    @Override
    public String toString() {
        return "Father的toString{" +
                "fatherA=" + fatherA +
                '}';
    }
}
public class Son extends Father {
    private int sonA;
    private int A = 2;
    
    public Son(int fatherA, int sonA) {
        super(fatherA);
        this.sonA = sonA;
    }

    public void sameNameMethod() {
        System.out.println("子类中调用sameNameMethod方法");
    }
 
    public int getA() {
        return this.A;
    }
    
    @Override
    public String toString() {
        return "Son的toString{" +
                "sonA=" + sonA +
                '}';
    }
}
public class TestMain {

    public static void main(String[] args) {
        int fatherA = 0;
        int sonA = 1;
        Father f = new Son(fatherA, sonA);
        System.out.println(f.toString());
        f.sameNameMethod();
        System.out.println(f.getA());
    }
}
/** 控制台打印:
    Son的toString{sonA=1} 
    子类中调用sameNameMethod方法
    2
**/



04


try catch finally的执行


针对如下代码块:

try {
 // 尝试运行的程序代码 
catch(//异常类型 异常变量名) {
    // 异常处理代码
finally {
    // 异常发生之后,方法返回之前,总是要执行的代码
}

结论如下:

1、finally语句一定会执行。

2、当在执行try代码块时,若在中间某一句捕获到异常,则这一句之后的代码都不会再执行。

3、当存在多个catch代码块时,会从上至下匹配到第一个catch后,就抛出异常。

4、先抛出子类异常,再抛出父类异常。

大家可以随便写点而代码试试~



05


总结


这些点很杂,但又经常考,因此阿清在这里整理一下~

希望能够帮助大家更好地记忆这些零散的Java语法,祝大家乘风破浪,披荆斩棘。

关注六只栗子,面试不迷路!

整理零碎的Java语法

🏋️别人爱举铁我爱举个🌰

🧩知识分享 | 面试经验 | 面试辅导 | 408辅导

🌏领域:前端 | 后端 | 深度学习 | 大数据 | 项目管理

🔎语言:Java|Python

🔗微信公众号搜索“六只栗子” | 邮箱联系:sixchestnuts@163.c


作者    阿清

编辑   一口栗子  


本文内容原创自“六只栗子”团队

©原创IP版权在手,未经授权商用必究


整理零碎的Java语法

整理零碎的Java语法

整理零碎的Java语法

整理零碎的Java语法

原文始发于微信公众号(六只栗子):整理零碎的Java语法

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/88200.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!