java基础知识拾遗(二)

1.finally

public static int func (){
        try{
            return 1;
        }catch (Exception e){
            return 2;
        }finally {
            return 3;
        }
    }
public static int func (){
        try{
            throw new Exception();
        }catch (Exception e){
            return 2;
        }finally {
            return 3;
        }
    }

返回值均为3;这表明finally块的代码会在正常return之前被执行;

2.java异常处理类之间的关系

异常的继承结构:基类为 Throwable,Error 和 Exception 继承 Throwable,RuntimeException 和 IOException 等继承 Exception

非 RuntimeException 一般是外部错误,其必须被 try{}catch 语句块所捕获

Error 类体系描述了 Java 运行系统中的内部错误以及资源耗尽的情形,Error 不需要捕捉

3.线程run()方法

线程类想要开辟新线程必须执行start()方法,start()方法内部会调用该类已实现的run()方法.如果执行run(),相当于执行一个普通方法,属于当前线程.

4.int 和 Interger比较

int i=0;
Integer j = new Integer(0);
System.out.println(i==j);
System.out.println(j.equals(i));

改代码输出:true,true;

int类型与Integer进行比较,Integer会自动拆箱成Int类型再比较,所以为true。

5.String对象参数传递

如果是以String s = "str"创建,则按值传递,因为按这种方式创建的对象如果字面量相同,则只存在一个对象在方法区中

6.i++和++i

public static int test(int c) {
        c = c++;
        return c;
    }
    public static void main(String [] args){
        System.out.println(test(0));
    }

输出0;

看看test方法的字节码

0: iload_0 //加载第一个参数到堆栈
1: iinc 0, 1 //对本地变量区的第一个变量进行自增操作
4: istore_0 //将第一步加载的参数数值赋给本地变量区的第一个变量
5: iload_0  //将本地变量区的第一个变量加载到堆栈
6: ireturn   //返回上一步加载到堆栈的变量
public static int test(int c) {
        c = ++c;
        return c;
    }
    public static void main(String [] args){
        System.out.println(test(0));
    }

输出1;

同样来看看test方法的字节码

 0: iinc          0, 1//将本地变量区的第一个变量进行自增操作
 3: iload_0      //加载本地变量区的第一个变量到堆栈
 4: istore_0      //将上一步加载的变量赋给本地变量区的第一个变量(即本身)
 5: iload_0      
6: ireturn

 事实上i++和++i在底层的实现都是先自增,区别在于返回值.i++返回自增前的值,++i返回自增后的值

7.if(x=y)

public static void main(string[]args){
        int x=3;
        int y=1;
        if(x=y)
            system.out.println(“Not equal”);
        else
            system.out.println(“Equal”);
     }

编译时错误

if()括号内要求布尔值,发现int类型

C语言中
当if语句中的条件为赋值语句时,实际上是将赋值后的结果与0进行比较【左值】
if(1)  由于1>0  所以认为是true
但java直接将赋值后的结果放入if()中
 
8.子类构造函数是否要显示调用父类构造函数
class Person {
    String name = "No name";
    public Person(String nm) {
        name = nm;
    }
}
class Employee extends Person {
    String empID = "0000";
    public Employee(String id) {
        empID = id;
    }
}
public class Test {
    public static void main(String args[]) {
        Employee e = new Employee("123");
        System.out.println(e.empID);
    }
}

编译时错误

子类的构造方法总是先调用父类的构造方法,如果子类的构造方法没有明显地指明使用父类的哪个构造方法,子类就调用父类不带参数的构造方法。
而父类没有无参的构造函数,所以子类需要在自己的构造函数中显示的调用父类的构造函数。

9.异常捕捉

public void getCustomerInfo() {
        try {
            // do something that may cause an Exception
        } catch (java.io.FileNotFoundException ex) {
            System.out.print("FileNotFoundException!");
        } catch (java.io.IOException ex) {
            System.out.print("IOException!");
        } catch (java.lang.Exception ex) {
            System.out.print("Exception!");
        }
    }
①如果捕获到了一种类型的异常,后面层级更高的异常就不会执行了
②代码块中的do something that may cause an Exception说明程序运行时只会抛出一个异常, 但没有 指明
是什么异常,三种异常均有可能。对于某个异常,只会被捕获一次.

10.接口变量

public interface IService {String NAME="default";}

相当于

public static final String NAME="default";

11.final与继承

class Car extends Vehicle
{
    public static void main (String[] args)
    {
        new  Car(). run();
    }
    private final void run()
    {
        System. out. println ("Car");
    }
}
class Vehicle
{
    private final void run()
    {
        System. out. println("Vehicle");
    }
}

以上代码输出Car

首先final声明的方法是不能被覆盖的,但是这里并不错误,因为方法是private的,也就是子类没有继承父类的run方法,因此子类的run方法跟父类的run方法无关,并不是覆盖。new Car().run()也是调用子类的run方法。

原文地址:https://www.cnblogs.com/vinozly/p/5398125.html