一、关于包
1.1简介
在Java中,package(包)是用来组织和管理类(class)的一种机制。包可以将相关的类进行分组,有助于代码的管理和组织。
作用:
包可以避免类名冲突:不同包中的类可以使用相同的类名,因为它们的完全限定名(package + 类名)不同。
提供了命名空间管理:通过包的结构,可以很方便地管理类和其他资源。
命名规范:
包名一般使用小写字母,多个单词之间可以使用.分隔,如com.example.myapp。
包名应该具有唯一性,通常使用公司域名的倒置形式来确保包名的唯一性。
包的声明:
在Java类的文件中使用package语句声明所属的包,通常在文件开头声明。
例如,package com.example.myapp; 表示该类属于com.example.myapp包。
包的导入:
使用import语句将其他包中的类引入到当前类中使用。
可以使用通配符*来导入整个包或特定类,例如import java.util.*; 或 import java.util.ArrayList;。
例如:
import java.util.Date;
import com.example.myapp.MyClass;
这允许在代码中直接使用Date和MyClass,而不需要每次都写出完整的包名。
包的结构:
包是按照目录结构来组织的,包名中的.会被转换成文件系统的路径分隔符。
例如,包com.example.myapp对应的目录结构为com/example/myapp。
标准Java包:
Java提供了许多标准的包,如java.lang、java.util、java.io等,用于提供常用类和接口。
标准库中的类无需导入即可直接使用。
1.2java常用包
Java提供了大量的标准库包,这些包包含了各种功能丰富的类和接口,以支持广泛的应用程序开发。以下是一些Java中最常用和重要的包及其简要介绍:
java.lang - 这是Java语言的核心包,包含了许多基本类,如String、Math、System、Thread和Runnable等。这个包中的类被自动导入到每个Java程序中,无需显式导入。
java.util - 包含集合框架、日期时间功能、事件模型、随机数生成器等。常见的类有ArrayList、HashMap、HashSet、Date、Calendar、Random等。
java.io - 提供了输入输出功能,包括文件读写、序列化和网络通信等。重要的类有File、FileInputStream、FileOutputStream、BufferedReader、PrintWriter、InputStream、OutputStream等。
java.net - 包含了编写网络应用程序所必需的类,如URL、URI和网络连接的管理。主要类有URL、URLConnection、Socket、ServerSocket等。
java.nio - 提供了更高效的I/O操作方法,支持直接内存访问,是java.io的一个补充。关键类包括ByteBuffer、CharBuffer、Channels和Selectors。
java.sql - 包含了用于处理数据库相关的类和接口,如Connection、Statement、ResultSet等,支持JDBC(Java数据库连接)。
java.awt - 是Java的原始图形用户界面工具包,包含了创建桌面应用程序所需的基本组件和工具类。
java.swing - 建立在AWT之上,提供了一套更加强大的图形用户界面组件,用于创建复杂的桌面应用程序。
java.security - 提供了安全性和加密功能,包括安全的随机数生成、加密、摘要、签名等。主要类有KeyStore、Cipher、MessageDigest、Signature等。
java.math - 包含了BigDecimal类,用于任意精度的整数和定点数的数学运算。
java.concurrent - 包含了并发编程的工具类,如线程池、同步器、并发集合等。关键类有ExecutorService、Future、Callable、CountDownLatch、CyclicBarrier、ConcurrentHashMap等。
java.time - Java 8引入的新的日期和时间API,提供了更加易用和更加灵活的日期时间处理类,如LocalDate、LocalTime、LocalDateTime、ZonedDateTime、Duration、Period等。
这些包构成了Java标准库的基础,是开发Java应用程序时不可或缺的部分。
二、java.lang包
2.1关于java.lang包
2.1.1简介
java.lang 包是 Java 程序中最基本和最核心的包。它包含了 Java 编程语言的基础类,这些类是每个 Java 程序的构建块。由于其重要性,java.lang 包中的类被自动导入到所有的 Java 程序中,无需显式地使用 import 语句。
java.lang包是java语言的核心,它提供了java中的基础类。包括基本Object类、Class类、String类、基本类型的包装类、基本的数学类等等最基本的类。
2.1.2常用类和接口
Object - 所有类的根类,提供了一些基本的方法,如 toString()、equals(Object)、hashCode() 和 getClass()。
String - 表示不可变的字符串。String 类提供了创建和操作字符串的方法,如 length()、charAt(int)、substring(int, int)、indexOf(String) 等。
Math - 提供了基本的数学运算功能,如 abs()、sqrt()、random()、pow(double, double) 等。
System - 提供了与系统相关的方法,如 out(PrintStream 类型的 System.out)、err(PrintStream 类型的 System.err)、exit(int)、gc() 等。
Thread - 用于创建和控制线程的类。Thread 类提供了线程的创建、启动、等待、同步和通信的方法。
Runnable - 一个标记接口,其实现类的对象可以作为线程执行。通常与 Thread 类一起使用,以定义线程的任务。
Throwable - 所有错误和异常的超类。Exception 和 Error 是 Throwable 的两个主要子类。
Exception - 程序可以处理的异常的基类。RuntimeException 和 IOException 是 Exception 的常见子类。
RuntimeException - 非检查性异常的超类,表示那些可能在Java虚拟机正常运行期间抛出的异常,如 NullPointerException、IllegalArgumentException 等。
ClassLoader - 用于动态加载 Java 类的类。Java 虚拟机会使用 ClassLoader 来加载 .class 文件。
StringBuilder 和 StringBuffer - 可变字符串类,提供了可修改字符串的方法。StringBuffer 是线程安全的,而 StringBuilder 不是。
Long、Integer、Double、Float 等 - 提供了基本数值类型的包装类,以及一系列静态方法来操作这些数值类型。
2.2Object类
2.2.1简介
java.lang.Object 是 Java 语言中所有类的根类。这个类提供了一些基本的方法和行为,这些方法和行为在所有的 Java 类中都是可用的,因为它们最终都是从 Object 类继承而来的。
Java Object 类是所有类的父类,也就是说 Java 的所有类都继承了 Object,子类可以使用 Object 的所有方法。
Object 类可以显式继承,也可以隐式继承,以下两种方式是一样的:
1.显式继承:
public class Runoob extends Object{
}
2.隐式继承:
public class Runoob {
}
2.2.2构造方法
Object 类是所有类的根类,它包含了一些所有类都具有的通用方法,比如 toString、equals、hashCode 等。由于 Object 类是所有类的祖先,因此它并没有显式定义构造方法。换句话说,Object 类的构造方法是由 Java 虚拟机隐式提供的,它没有任何参数,也没有任何操作,因为它并不需要进行实例化。
2.2.3方法
toString() - 返回对象的字符串表示,通常返回类的名称和对象的哈希码的无符号十六进制表示。可以通过重写此方法来提供对象的自定义字符串表示。
equals(Object obj) - 用于比较两个对象是否相等。默认实现是比较对象的引用,即只有当两个对象是同一个实例时才返回 true。可以通过重写此方法来提供自定义的相等性比较逻辑。
hashCode() - 返回对象的哈希码,这是一个用于哈希表的整数值。默认实现依赖于对象的内部状态。通常,当你重写 equals 方法时,也应该重写 hashCode 方法,以确保 equals 方法的相等性与 hashCode 方法的一致性。
getClass() - 获取运行时对象的类信息,返回一个 Class 对象,表示对象的类型。
clone() - 创建并返回对象的一个副本。默认实现是浅拷贝,即复制对象的引用,而不是对象本身。可以通过实现 Cloneable 接口并重写 clone 方法来提供深拷贝或其他自定义的克隆行为。
wait() - 使当前线程等待,直到另一个线程调用此对象的 notify() 或 notifyAll() 方法,或者直到超过指定的超时时间。
notify() 和 notifyAll() - 用于唤醒在此对象监视器上等待的单个线程(notify())或所有线程(notifyAll())。
finalize() - 在垃圾收集器决定回收对象之前,由垃圾收集器调用此方法。这个方法可以用于执行清理操作,比如释放资源。然而,由于 finalize() 方法的调用时机不确定,以及可能对性能的影响,通常建议使用 try-with-resources 语句和自动资源管理器来管理资源,而不是依赖 finalize() 方法。
2.2.4示例
toString方法
Object 类中的 toString() 方法是 Java 中一个非常重要的方法,它被用来返回对象的字符串表示。这个字符串表示通常包含了对象的类名和它的哈希码值的无符号十六进制表示。
/**
* Returns a string representation of the object. In general, the
* {@code toString} method returns a string that
* "textually represents" this object. The result should
* be a concise but informative representation that is easy for a
* person to read.
* It is recommended that all subclasses override this method.
*
* The {@code toString} method for class {@code Object}
* returns a string consisting of the name of the class of which the
* object is an instance, the at-sign character `{@code @}', and
* the unsigned hexadecimal representation of the hash code of the
* object. In other words, this method returns a string equal to the
* value of:
*
*
* getClass().getName() + '@' + Integer.toHexString(hashCode())
*
*
* @return a string representation of the object.
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
默认实现
在 Object 类中,toString() 方法的默认实现返回一个字符串,格式通常如下:
"[类名@哈希码]"
其中,类名是对象所属的类的名称,哈希码是对象的哈希值的无符号十六进制表示。哈希码是基于对象的内部状态计算得来的,通常是对象的内存地址的某种变换。
重写 **toString()** 方法
由于 toString() 方法在 Object 类中的实现并不具有太多的描述性,因此在实际编程中,通常会根据需要重写这个方法,以提供更有意义的信息。例如,一个 Person 类可能会重写 toString() 方法来返回包含人名和年龄的字符串。
下面是一个重写 toString() 方法的例子:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
在这个例子中,toString() 方法返回了一个包含 Person 对象 name 和 age 属性的字符串。
使用 **toString()** 方法
toString() 方法在 Java 中的使用非常广泛,它被用于打印对象信息、显示在用户界面上、记录日志等场景。例如,可以使用 System.out.println() 方法打印对象的字符串表示:
Person person = new Person("Alice", 30);
System.out.println(person); // 输出:Person{name='Alice', age=30}
在上述代码中,由于 Person 类重写了 toString() 方法,所以 System.out.println() 方法能够打印出自定义的字符串表示。
在IDEA中高效使用toString
第一步:alt +insert
第二步:选中toString()
第三步:将所需参数选中,点击OK!
生成你所需的方法,也可在此基础上进行修改达到最佳效果!
equals方法
Object类的equals()方法用于比较两个对象是否相等。默认情况下,equals()方法实现的是比较两个对象的引用是否相同,即它检查两个对象的内存地址是否一致。如果两个对象的引用指向同一个内存位置,equals()方法返回true;否则返回false。
public boolean equals(Object obj) {
return (this == obj);
}
重写**equals()** 方法
在实际应用中,通常需要根据对象的内容而不是它们的引用来比较它们是否相等。因此,经常需要重写equals()方法来提供自定义的相等性比较逻辑。重写equals()方法时,通常也需要重写hashCode()方法,以确保相等的对象具有相同的哈希码,这是hashCode()方法的一般约定。
以下是一个重写equals()方法的示例:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 重写equals方法
@Override
public boolean equals(Object obj) {
// 如果对象引用相同,或者obj是null,或者类型不匹配,则不平等
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
// 转换为Person类型以安全地访问属性
Person person = (Person) obj;
// 比较name和age属性
return this.name.equals(person.name) && this.age == person.age;
}
// 重写hashCode方法以保持与equals的一致性
@Override
public int hashCode() {
int result = 17;
result = 31 * result + name.hashCode();
result = 31 * result + age;
return result;
}
}
在这个示例中,Person类重写了equals()方法,以比较两个Person对象的name和age属性是否相同。同时,也重写了hashCode()方法,以确保具有相同属性的Person对象具有相同的哈希码。
使用**equals()** 方法
当你创建了自定义的equals()方法后,可以使用它来比较两个对象是否具有相同的数据:
Person person1 = new Person("Alice", 30);
Person person2 = new Person("Alice", 30);
Person person3 = new Person("Bob", 30);
boolean areEqual1 = person1.equals(person2); // 返回true,因为他们具有相同的属性
boolean