Java 基础考核(一)

大家好呀,我是小笙!

基础考核篇

1.抽象类、接口、普通类的区别?

我们以普通类为基准点来进行比较分析他们之间的关系

抽象类和类的区别:
1.不能被实例化(思考:那为什么要构造器?)
说明:抽象类的构造器不是用于抽象类本身,更多是为了在调用子类的构造器的时候,调用父类的构造器进行参数的初始化
2.抽象类可以使用抽象方法,但是普通类不行

// 抽象类组成
public abstract class AbstractClassExample {
    // 属性
    private int y;
    // 静态属性
    public static int x;
    // 构造器:可以被子类用super关键字调用构造器
    public AbstractClassExample(){}
    // 代码块
    {}
	// 抽象方法:不能使用private,final和static修饰符,因为这些修饰符都是和重写相违背的
    // 访问修饰符 abstract 返回类型 方法名(参数列表); // 没有方法体
    public abstract void func1();
    // 普通方法
    public void func2() {
        System.out.println("func2");
    }
    // 静态方法
    public static void func3() {
        System.out.println("func3");
    }
}

接口和普通类的区别:
1.不能被实例化
2.改变了类的特性:可以实现接口之间的多继承,类与接口之间的多实现

// 接口组成
// 访问修饰符 interface 接口名{}  访问修饰符:public 和默认  
interface Interface{
    // 静态属性 默认是public static final修饰
    // 可以通过 接口名.属性名来访问属性
    int n1 = 10;
    
    // 静态内部类 默认是public static final修饰,可以实现当前接口
    class InterfaceInnerClass{};
    
    // 静态方法  默认是public修饰
    static void method3(){
        System.out.println("静态方法");
    }

    // 抽象方法  默认是public abstract
     void method1();

    // 在jdk1.8之后,出现默认方法 添加default关键字  默认是public 
    default public void method2(){
        System.out.println("默认方法");
    }
} 

抽象类 Vs 接口

  • 从设计层面上看,抽象类提供了一种 IS-A 关系,那么就必须满足里式替换原则,即子类对象必须能够替换掉所有父类对象。而接口更像是一种 LIKE-A 关系,它只是提供一种方法实现契约,并不要求接口和实现接口的类具有 IS-A 关系
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口
  • 接口的成员只能是 public 修饰的,而抽象类的成员可以有多种访问修饰符
  • 抽象可以有普通方法(含有方法体),接口只能是默认方法(带有default关键字)

使用选择

使用接口:

  • 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法
  • 需要使用多重继承(通过多个接口实现弥补单继承)

使用抽象类:

  • 需要在几个相关的类中共享代码

  • 需要能控制继承来的成员的访问权限,而不是都为 public

常见面试题
1.接口中可以有构造函数嘛?
构造函数的核心用处:创建对象和初始化参数
接口不能被实例化,接口参数都是静态常量,不需要初始化参数,因此不需要构造器
2.谈谈对接口编程的理解
接口我们可以理解为定义某种规范,就是比如 MySQL 数据库想要Java去操作,必须实现Java给出的规范,也就是驱动;接口编程时功能编程,能够很好的降低程序的解耦

2.异常机制如何实现?

异常是什么?
异常就是程序代码出现了问题,但是非致命问题(错误 error 就是致命问题,程序必须结束:栈溢出等),我们需要去处理这些异常;异常机制就是发现异常,封装异常,处理异常的一种机制
为什么需要发现异常?
异常的精准定位能够更加高效地发现问题然后解决问题

异常体系图

在这里插入图片描述

异常类的种类

在这里插入图片描述
编译时异常:在代码编译前就出现的异常必须解决之后才可以运行
运行时异常:代码被加载到虚拟机中运行时候出现的异常
注意:需要记住几个异常类的例子,编译时异常往往时找不到,运行时异常往往时逻辑上的错误

异常的处理

  • try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
  • catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。
  • finally – finally语句块总是会被执行。它主要用于回收在try块里打开的资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
  • throw – 用于抛出异常。
  • throws – 用在方法签名中,用于声明该方法可能抛出的异常。
public void exceptionClass throws Exception{ // 方法无法捕获异常,向调用者抛出异常
	// try - catch - finally格式如下
	try{
	    // 代码可能有异常
	    // 如果没有出现异常,则执行try块中所有的语句,反之有出现异常,则不再执行try块中剩余的语句,抛出异常
	}catch(NullPointerException e){ 
	    // 捕获异常
	    // 1.当异常发生时,才会执行catch内的代码
	    // 2.系统将异常封装成Exception对象e,传递给catch
	    // 3.同一个 catch 也可以捕获多种类型异常,用 | 隔开
	}catch(RuntimeException e){ 
	    // 可以有多个catch语句进行捕获不同的异常,要求子类异常在父类异常之前,不然就没有子类异常存在的意义
	    throw new RuntimeException("运行时异常"); // 在方法内无法解决,可以抛出运行时异常
	}finally{
	    // 不管是否有异常,一般都会执行
	    // 总结:finally遇见如下情况不会执行
	    // 1.在前面的代码中用了System.exit()退出程序。
	    // 2.finally语句块中发生了异常。
	    // 3.程序所在的线程死亡。
	    // 4.关闭CPU。
	}
}

补充:throw或者throws 抛出形式
在这里插入图片描述
常见面试题
1.请说明JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。

Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理。用try来指定一块预防所有”异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的”异常”的类型。throw语句用来明确地抛出一个”异常”。throws用来标明一个成员函数可能抛出的各种”异常”。Finally为确保一段代码不管发生什么”异常”都被执行一段代码。可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,”异常“的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种”异常”进行处理,堆栈就会展开,直到遇到有处理这种”异常”的try语句。

3.对泛型的理解

泛型:字面上的意思就是广泛的类型,传入类型是不确定的,只有在编译之后才会被确认
泛型特点:
1.可以使用任意字母A-Z,用作占位符,表示传入的类型(可以用于属性类型,方法参数传入类型,方法返回类型)
2.只能指代引用类型的数据(因为在编译之前需要进行类型擦除,裸类型为 Object 类型(准确的来说是替换成它们非泛型上界),但是基本数据类型不能和 Object 类型进行转换)
3.指定传入类型,但是可以真实传入该类型的子类型,类似于向上转型的用法

// 自定义泛型
class Template<E>{
    E filed;
	// 方法返回
    public E method(){
        return filed;
    }
	// 方法传入
    public Template(E filed) {
        this.filed = filed;
    }
}

泛型擦除的原理:
java里面的泛型只存在于源代码里面,一旦经过编译之后,所有的泛型都会被擦除掉,全部被替换为原来的裸类型 Object 类型,并在对元素进行访问和修改的时候,才会加上强制类型转换

类型擦除的优点
实现简单,运行期也能够节省一些类型所占的内存空间

类型擦除的缺点

1.使用类型擦除直接导致了对于原始的数据类型无法支持,比如int,long这种,因为java不支持Object类型和基本数据类型之间的强制类型转换,也就是说一旦类型擦除之后,就没法在进行 类型转换了。也正是这样,现在的泛型都是不支持原始类型的,比如ArrayList< Integer >,而不能使用ArrayList< int >

2.运行期间无法获得泛型类型信息。因为泛型都被擦除了,都被替换成了裸类型。这样就导致了下面的程序都会报错,比如无法使用泛型来创建对象,或者数组

常见面试题
1.在开发中使用泛型取代非泛型的数据类型(比如用ArrayList取代ArrayList),程序的运行时性能会变得更好(错误)

解析:泛型仅仅是 java 的语法糖,它不会影响 java 虚拟机生成的汇编代码,在编译阶段,虚拟机就会把泛型的类型擦除,还原成没有泛型的代码,顶多编译速度稍微慢一些,执行速度是完全没有什么区别的

2.什么是泛型?泛型的作用?

  • Java 泛型(Generics)是 JDK 5 中引入的一个新特性。
  • 使用泛型参数,可以增强代码的可读性以及稳定性。编译器可以对泛型参数进行检测,并且通过泛型参数可以指定传入的对象类型。比如 ArrayList<Persion> persons = new ArrayList<String>() 这行代码就指明了该ArrayList 对象只能传入 Persion 对象,如果传入其他类型的对象就会报错。
  • 可以用于构建泛型集合。原生 List 返回类型是 Object ,需要手动转换类型才能使用,使用泛型后编译器自动转换。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Al_tair

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值