看招,Java 基础十连击!

面向对象

面向对象是一种编程思想,从业务中抽象出一个个类,类中包含属性和方法,相比直接实现函数功能的面向过程,更容易维护和扩展,有封装、继承、多态三大特性:

封装:将对象的属性私有化,对外只提供接口访问,从而隐藏内部实现,提高程序安全性。
继承:从已有类得到继承信息创建新类的过程,实现了代码的复用。

  • 子类拥有父类所有属性和方法,但无法访问访问父类私有属性和方法。
  • 子类可以拥有自己的属性和方法。
  • 子类可以重写父类方法。

多态:分为编译时多态(重载)和运行时多态(重写)

  • 重载:指同一个类中同名的方法有不同的参数列表,注意不能根据返回类型进行区分。
  • 重写:发生在子类与父类之间,子类重写父类的方法具有相同的返回类型、更好的访问权限。

实现多态分两步,一是子类继承父类并重写父类的方法,二是用父类型引用子类型对象。这样,同样的引用调用同样的方法,就会因为子类对象的不同而执行不同的操作。

但面向对象不能很好的实现业务逻辑与非业务代码,如安全、日志、事务,的解耦,需要 AOP 来进行补充。

String

String:

  • 是不可变类,原生的保证了线程安全;
  • 底层用被 final 修饰的 char 数组保存数据,Java 9 改用 byte;
  • 由于不可变,所以每次改变,都要产生新的 String 对象,影响性能,所以只适合操作少量数据。

操作大量数据要用 StringBuffer、StringBuilder,它们继承于 AbstractStringBuilder,底层用可修改的 char 数组,Java 9 改为 byte;不同在于:

  • StringBuffer 通过 synchronized 保证了线程安全,适合并发下使用,但有额外的性能开销;
  • StringBuilder 不是线程安全的,性能更高,适合单线程下使用。

拼接字符串用的加号,底层就是调用了 StringBuilder,但不建议在多表达式或循环内直接用,因为会频繁创建 StringBuilder 对象。更好的做法是,手动创建 StringBuilder 对象,调用它的 append 方法进行拼接。

数据类型

Java 的数据类型分为基础类型和引用类型两种。

基础类型有:

  1. 整型:byte、short、int、long,分别为 8、16、32、64 位,数据范围是 -2 的位数 -1次幂 ~ 2 的位数 -1 次幂 -1。比如:int,-231 ~ 231-1 。
  2. 浮点型:float、double,分别为 32、64 位,float 赋值必须加 F。
  3. 布尔型 boolean:只有 true,false 两个取值。
  4. 字符型 char:16位,存储 Unicode 码,用单引号赋值。

每种基本类型都有对应的包装类型:

  • 自动装箱:自动将基本类型转换为包装类型。底层通过调用包装类型的 valueOf 方法实现,比如 Integer.valueOf(),它会缓存 -128 到 127 的数据,以提高性能,。
  • 自动拆箱:自动将包装类型转换为基本类型。

引用类型可细分为类、接口、数据类和泛型。Java 的泛型是通过类型擦除实现的伪泛型,即泛型信息在编译过后便会擦除。数组类由 JVM 直接生成,没有字节流。只有类和接口才有对应的字节流,需要通过类加载器去加载。

抽象类和接口

抽象类:不能实例化的类,用于重用代码。

  • 可以定义构造函数;
  • 访问权限可以是 public、protected、default。(public 所有类,protected 包内类及子类,default 包内类,private 本类)
  • 方法可以有抽象方法和具体方法;(可以没有抽象方法)

接口:抽象方法的集合,用于定义 API 和分离实现。

  • 不能实例化和定义构造函数。
  • 变量默认为 public static final。public 允许所有类访问。static 修饰为类变量,因为接口不能实例化。final 则避免被实现类修改。
  • 方法只能是抽象方法。Java 8 后,开始有静态方法和默认实现。

Java 中定义了非常多接口,常用的比如集合的 Collection 和 Map。

equals

==

== 是运算符:

  • 对于基本数据类型,比较的是值;
  • 对于引用类型,比较的是内存地址。

equals() 是 Object 的方法,用于比较对象是否相等,不能比较基本类型。

  • 默认实现是,用 == 比较对象的内存地址;
  • 一般会重写,转换成值的比较。

hashCode

equals()、hashCode() 都是 Object 类的方法:

  • equals():用于比较两个对象是否相等,不能比较基本数据类型;默认实现是用 == 比较对象的引用地址,一般会重写转换成值的比较。
  • hashCode():返回对象的哈希值(一个 int 整数),用于确定对象在哈希表中的索引位置。

它们常用在 HashSet、HashMap 等集合的判重:

  • 如果仅用 equals(),那么集合中有多少对象,equals() 就要执行多少次,时间开销很大。
  • 如果加入 hashCode,就能确定对象在哈希表的索引位置。后续比较中,若两个对象 hashCode 不同,也无需调用 equals(),减少 equals() 的次数,提高执行效率。

因为我们工作中常用到这些集合,为了提高效率,官方建议重写 equals() 一定要重写 hashCode()。

另外,如果两个对象相等,那么调用 equals() 返回 true,hashCode 也相等。
而如果 hashCode 相等,两对象却不一定相等,可能出现了散列冲突。

final

修饰类,表示被不可继承。修饰方法,表示不可被重写。从而保护类的基础功能不被篡改。

修饰变量:

  • 对于基础类型,使其数值不变,可用于保护只读数据,减少额外的同步开销。
  • 对于引用类型,使其引用不变,但对象本身行为不受影响。

异常

Exception、Error

Exception 和 Error 都是 Throwable 的子类,区别在于:

  • Exception 表示程序可以处理的异常,可以捕获且可能恢复,分为受检查异常和运行时异常:
    • 受检查异常:必须显式地进行捕获处理,否则编译不通过,如 IOException 等;
    • 运行时异常:通常是可以编码避免的逻辑错误,编译能通过,但是一运行就终止,如 NullPointerException、ClassCastException(类型转换)、ConcurrentModificationException 等。
  • Error 表示程序无法处理的错误,多跟 JVM 相关,如 OutOfMemoryError(内存溢出)、StackOverflowError(栈溢出) 等。

finally

finally 是异常处理语句 try-catch-finally 中的一部分,用于保证其中的代码总是被执行。
不执行情况:程序在进入 try 前就异常,或者在 try 中执行 exit() 强制退出了。

  • 当 finally 有 return 时,无论 try、catch 是否有,最终返回的都是 finally 中 return 的值。
  • 当 finally 无 return,try、catch 有时,程序会先将返回值暂存,等执行完 finally 再返回;如果返回值是基础类型,那么 finally 对它无影响,如果是引用类型,因为暂存的是内存地址,所以会返回 finally 对它的修改值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值