Java 扫盲(一)基础中的基础

Java 扫盲(一)基础中的基础

根据 TIOBE,Java 直到 2023 年依然是主流编程语言。在 Java 8 以前掌握这门语言是一件比较简单的事情,但在 8 之后学习曲线开始变陡,即使经过多次减负学习成本也在慢慢增加,尤其需要耗费在学习各种框架的原理和应用之上。_Java 扫盲系列_不会像官方 Doc 一样事无巨细地对语法絮絮叨叨不停,而是会按我个人喜好将其拆解分析,着重于方法论上。

TIOBE Index 2023

在学习一门编程语言之前,按照惯例,附上三篇大牛漫谈雄文,分别是 Paul GrahamBruce EckelPeter Norvig

⭐IT 大牛谈编程语言(网文 3 篇)译自 阮晓寰

Object 通用方法

在 Java 中,Object 类是所有类的祖先,因此我们应该先去见见这个 “老祖宗”,看看它所定义的常用方法。

  • getClass 返回该对象运行时类的信息,我们常用这个方法获取对象的类名
  • toString 默认返回类似 “对象名 @14114e1c” 这种形式,后面跟着的是_散列码的 16 进制表示_

hashCode

hash 中文译作 “散列”,本身代表一种基本的计算机概念,每个 hash 都代表一种哈希生成算法,而 Java 中的 hashCode 会返回一个和内存地址相关的 32 位整数,从而利用对象唯一性来保证其哈希码的唯一性。

equals

原始的 equals 方法只是让两个对象用 == 直接比较,因此 String 类有重写该方法,当我们设计类的时候想要正确比较同样也需要重写这个方法。如

1
2
3
4
5
6
7
8
9
10
11
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

EqualExample that = (EqualExample) o;

if (x != that.x) return false;
if (y != that.y) return false;
return z == that.z;
}

clone

拷贝又分为浅拷贝和深拷贝,浅拷贝就是返回同一个引用对象,而深拷贝就是返回和原始对象的引用类型但引用的是不同对象,前者基本没啥意义,我们谈拷贝默认指深拷贝。在 Java 中,如果一个对象没有实现 Cloneable 接口,默认抛出 CloneNotSupportedException,另外 clone 方法是复制一个数组最快的方法。

为什么我们需要克隆方法而不是直接用 new 创建一个新对象?因为用 new 创建对象会耗费大量时间。

如何在实际应用中使用 clone?如果是已经设计部署好的类,我们可以定义一个父类并实现 Cloneable 接口。

下面,用一个实际例子说明如何正确使用 clone 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class demo {
public static void main(String[] args) throws CloneNotSupportedException {
B b = new B("X ming", 12);
System.out.println(b);
B c = (B)b.clone();
System.out.println(c);
}
}

class A implements Cloneable{

}

class B extends A{
String name;
int age;

B (String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return super.toString() + ", " + name + ", " + age;
}

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

wait, notify 和 notifyAll

线程类指那些继承自 Thread 的类,唤醒指让线程状态从阻塞态转为就绪态。

Thread status

wait, notifynotifyAll 方法是 Java 留给线程通信的,本质是修改锁对象状态。比如其中的 notify 就是用来唤醒单个线程的。

1
2
3
4
5
6
7
8
9
synchronized( lockObject )
{
while( ! condition )
{
lockObject.wait();
}

//take the action here;
}

String

Java 中的 String 底层是 char 数组,但是实现了 CharSequence 接口的类还有 StringBufferStringBuilder。我们会用 StringBuilder 创建_可变字符串_,为什么专门提出这个概念,字符串不都是可以修改吗?并不是,Java 中的 Stringfinal 修饰的,当我们尝试修改它时,本质上是用一个新创建的实例去替换它。

String 对象有两种创建方式,一种是字面量创建的方式,如

1
2
String s1="Welcome";  
String s2="Welcome";//It doesn't create a new instance

用这种方式创建的字符串会直接再字符串常量池里面创建,大大节省内存效率。而另外一种创建方式就是 new 关键字了,略过不表。

反射

通过反射,我们可以知道一个对象的类是什么,它能够执行哪些方法。换句话说,我们可以在运行时通过反射调用 private 方法甚至构造一个对象。

Java lang pkg

我们的调试和测试工具就有用到反射,常用的框架比如 JDBCSpringSpringBoot 等都用到了反射,将数据库参数这种都写在配置文件中而不是代码里,让程序运行的时候自动去取。

总的来说,反射是帮助 Java 实现自动化必不可少的一个帮手。

异常

Java 用异常捕获来处理运行时发生的错误,比如 ClassNotFoundException, IOException, SQLException, RemoteException 等等。一般来说,异常的名称就告知程序员问题所在,而详细信息则描述了上下文信息。

异常又可以细分为 Checked ExceptionsUnchecked Exceptions,前者是可以恢复的。

Exceptions

我们可以利用 Java 的异常机制来检测失败和成功而不是笼统返回 true 或者 false

参考

【 1 】Java 新手的通病系列

【 2 】On Java 8

Java 扫盲(一)基础中的基础

https://zion4h.github.io/2023/04/05/java-basic-intro/

作者

zion h4

发布于

2023-04-05

更新于

2024-09-08

许可协议

评论