什么是类

在Java中,类是一种用来创建对象的蓝图或模板。它定义了对象的属性和行为。类是面向对象编程的基本概念之一,它允许开发人员创建具有相似属性和行为的对象。

public class Car {
    String color;
    int maxSpeed;

    void display() {
        System.out.println("颜色:" + color);
        System.out.println("最大速度:" + maxSpeed);
    }
}

在这个示例中,Car类定义了汽车对象的属性(颜色和最大速度)和行为(display方法)

类解决什么样的问题

类在Java中扮演着非常重要的角色,它们允许开发人员组织和管理代码,实现代码重用,并提供了一种结构化的方式来创建对象。

在类中,可以定义以下内容:
属性(成员变量): 用于描述对象的状态或特征。
方法(成员函数): 用于定义对象的行为或操作。
构造方法(Constructor): 用于初始化对象的特定状态。
代码块(Initialization Block): 用于执行特定的初始化操作。
内部类(Inner Class): 在一个类的内部定义另一个类。
接口(Interface): 用于定义类应该实现的方法契约。
抽象类(Abstract Class): 用于定义不能被实例化的类,通常包含抽象方法。
访问修饰符(Access Modifiers): 控制类、属性和方法的可见性。
静态成员(Static Members): 属于类而不是对象的成员。
继承(Inheritance): 允许一个类继承另一个类的属性和方法。
多态(Polymorphism): 允许不同类的对象对同一消息做出响应。
封装(Encapsulation): 将数据和行为打包在一个单元中,并对外部隐藏实现细节。

类的种类

抽象类(Abstract Class):不能被实例化,只能作为其他类的父类,可以包含抽象方法和非抽象方法。

接口(Interface):定义了一组方法的集合,但没有具体实现,一个类可以实现多个接口。

父类(Superclass):被其他类继承的类,也称为基类或超类。

子类(Subclass):从父类继承而来的类,可以拥有父类的属性和方法,并且可以新增自己的属性和方法。

内部类(Inner Class):定义在另一个类内部的类,可以访问外部类的成员。

匿名类(Anonymous Class):没有显式名称的类,通常用于创建实现某个接口或继承自某个类的对象。

包装类

包装类指的是Java中用来对基本数据类型进行包装的类,它们提供了一种将基本数据类型转换为对象的方式。在Java中,基本数据类型(如int、char、boolean等)不是对象,无法参与面向对象编程中的一些操作,比如放入集合类中。为了解决这个问题,Java提供了对应的包装类,用于将基本数据类型转换为对象。

常见的包装类及其对应的基本数据类型如下:

  • Integer:int
  • Long:long
  • Float:float
  • Double:double
  • Character:char
  • Boolean:boolean
  • Byte:byte
  • Short:short

String类

在Java中,String类是一个非常重要且经常使用的类,用于表示字符串对象。String类被设计为不可变的,也就是说一旦创建了String对象,其值就不能被修改。

它有很多特性:

不可变性: String对象一旦被创建,其值就不能被修改。任何对String对象的操作都不会改变原始对象,而是返回一个新的String对象。

常量池: 为了提高性能和节省内存,Java在编译时会将所有相同的字符串文字(字面值)放入常量池中,而对同一个字符串字面值的引用都指向常量池中的同一个实例。

字符串连接:String类提供了丰富的方法用于字符串的连接、截取、查找等操作,例如使用加号连接字符串:String result = str1 + str2;

不可变性带来的优点:

线程安全: 由于字符串不可变,多个线程可以安全地共享String对象。
缓存Hash值:由于String对象的不可变性,可以缓存其hash值,提高哈希表性能。
安全性:String对象不可变,避免了一些安全漏洞,如密码管理等。
常用方法:String类还提供了许多常用的方法,如length()、charAt()、substring()、indexOf()等,用于操作字符串的各种需求。

StringBuffer类

StringBuffer和String类的主要区别在于StringBuffer是可变的,可以修改其内容而不创建新的对象

可变性:StringBuffer对象是可变的,可以对其进行插入、追加、删除等操作,而不会创建新的对象,这在需要频繁修改字符串内容时非常有用。

线程安全:StringBuffer是线程安全的,所有的方法都是同步的(synchronized),因此多个线程可以安全地同时访问一个StringBuffer对象。

效率:由于StringBuffer是可变的,对字符串的修改操作不会像String那样每次都创建新的对象,因此在需要频繁修改字符串内容时,使用StringBuffer会更高效。

常用方法:StringBuffer类提供了丰富的方法来操作字符串,比如append()用于追加字符串、insert()用于在指定位置插入字符串、delete()用于删除部分字符串等。

StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // 追加字符串
sb.insert(5, "Java"); // 在指定位置插入字符串
sb.delete(5, 10); // 删除指定范围的字符串

String result = sb.toString(); // 将StringBuffer转换为String对象

StringBuilder类

StringBuilder和StringBuffer类似,都是可变的字符串序列,但StringBuilder不是线程安全的

可变性:StringBuilder对象是可变的,可以对其进行插入、追加、删除等操作,而不会创建新的对象,这在需要频繁修改字符串内容时非常有用。

非线程安全:与StringBuffer不同,StringBuilder并不是线程安全的,即不是同步的。这使得它在单线程环境中的操作更快速。

效率:由于StringBuilder是可变的,对字符串的修改操作不会像String那样每次都创建新的对象,因此在需要频繁修改字符串内容且不涉及多线程的情况下,使用StringBuilder会更高效。

常用方法:StringBuilder类提供了丰富的方法来操作字符串,比如append()用于追加字符串、insert()用于在指定位置插入字符串、delete()用于删除部分字符串等。

StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // 追加字符串
sb.insert(5, "Java"); // 在指定位置插入字符串
sb.delete(5, 10); // 删除指定范围的字符串

String result = sb.toString(); // 将StringBuilder转换为String对象

Math类

Math类是一个包含用于执行基本数学运算的静态方法的工具类。Math类提供了一系列用于执行常见数学运算的静态方法,例如对数运算、三角函数、指数函数、取整操作等。

静态方法:Math类中的所有方法都是静态方法,可以直接通过类名调用而无需创建Math对象。

常见方法:Math类提供了很多常见的数学运算方法,比如:

abs(double a):返回参数的绝对值。
sqrt(double a):返回参数的平方根。
pow(double a, double b):返回a的b次幂。
sin(double a)、cos(double a)、tan(double a):分别返回a的正弦、余弦和正切值(以弧度为单位)。
log(double a)、log10(double a):分别返回a的自然对数和以10为底的对数。
常量:Math类还定义了一些常用的常量,如PI表示圆周率π,E表示自然对数的底。

精度:Math类中的方法都是基于浮点数的运算,因此可能存在精度问题。在需要高精度计算时,可以考虑使用BigDecimal类。

double num = -10.5;
double absNum = Math.abs(num); // 绝对值
double sqrtNum = Math.sqrt(25); // 平方根
double powNum = Math.pow(2, 3); // 2的3次幂
double sinVal = Math.sin(Math.PI / 2); // 正弦值
double logVal = Math.log(10); // 自然对数

System.out.println("Absolute value: " + absNum);
System.out.println("Square root: " + sqrtNum);
System.out.println("Power: " + powNum);
System.out.println("Sine value: " + sinVal);
System.out.println("Natural logarithm: " + logVal);

System类

在Java中,System类是一个包含标准输入、输出和错误流、系统属性以及用于与外部环境交互的静态方法的工具类。System类提供了许多有用的方法,可以让我们与系统进行交互,执行标准I/O操作,获取和设置系统属性等。

静态方法:System类中的所有方法都是静态方法,可以直接通过类名调用而无需创建System对象。

标准I/O:System类提供了三个静态成员变量,分别代表标准输入流(System.in)、标准输出流(System.out)和标准错误流(System.err)。我们可以使用这些流来进行输入输出操作。

系统属性:System类还提供了一系列用于获取和设置系统属性的方法,比如getProperty(String key)用于获取指定的系统属性,setProperty(String key, String value)用于设置系统属性。

数组复制:System类中的arraycopy(Object src, int srcPos, Object dest, int destPos, int length)方法可用于将数组中的一部分内容复制到另一个数组中。

垃圾回收:System类中的gc()方法可以显式地请求系统进行垃圾回收。

// 从标准输入中读取用户输入
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.println("Hello, " + name);

// 使用标准输出打印消息
System.out.println("This is a message printed to the standard output");

// 获取系统属性
String javaVersion = System.getProperty("java.version");
System.out.println("Java version: " + javaVersion);

// 数组复制
int[] srcArray = {1, 2, 3, 4, 5};
int[] destArray = new int[5];
System.arraycopy(srcArray, 0, destArray, 0, srcArray.length);
System.out.println("Copied array: " + Arrays.toString(destArray));

// 请求系统进行垃圾回收
System.gc();

BigInteger类和BigDecimal类

在Java中,BigInteger类和BigDecimal类分别用于处理大整数和高精度的浮点数运算。它们提供了对超出普通整型和浮点数范围的数字进行精确计算的能力

BigInteger类:
概述:BigInteger类用于表示任意精度的整数,可以处理比long类型更大范围的整数。

特点:

不可变性:BigInteger对象一旦创建,其值就不可改变。
支持基本的算术运算(加、减、乘、除)以及位操作(与、或、异或等)。
提供了对整数的比较、取模、求幂等操作。
创建BigInteger对象:

通过构造方法传入整数值或使用静态方法如valueOf(long val)创建BigInteger实例。

BigDecimal类:
概述:BigDecimal类用于表示任意精度的有符号十进制数,主要用于需要精确计算货币和其他需要保持精度的应用场景。

特点:

不可变性:BigDecimal对象一旦创建,其值就不可改变。
支持基本的算术运算(加、减、乘、除)以及舍入操作。
可以设置精度和舍入模式。
避免浮点数运算可能导致的精度丢失问题。
创建BigDecimal对象:

通过构造方法传入字符串或使用静态方法如valueOf(double val)创建BigDecimal实例。

import java.math.BigInteger;
import java.math.BigDecimal;

// 使用BigInteger进行大整数计算
BigInteger num1 = new BigInteger("123456789012345678901234567890");
BigInteger num2 = BigInteger.valueOf(987654321098765432109876543210);
BigInteger sum = num1.add(num2);
System.out.println("Sum of BigIntegers: " + sum);

// 使用BigDecimal进行高精度浮点数计算
BigDecimal bd1 = new BigDecimal("123.456");
BigDecimal bd2 = BigDecimal.valueOf(45.678);
BigDecimal product = bd1.multiply(bd2);
System.out.println("Product of BigDecimals: " + product);

日期类

java.util.Date:在Java早期的版本中,Date类用于表示日期和时间,但由于其设计存在一些问题,已被大部分开发者废弃。

java.util.Calendar:Calendar类是一个抽象类,用于处理日期和时间相关操作。它提供了对年、月、日、时、分、秒等字段进行操作的方法。

java.util.GregorianCalendar:GregorianCalendar类是Calendar类的具体实现,提供了处理标准日历系统的功能。

java.time包:从Java 8开始引入了新的日期时间API,位于java.time包下,主要包括以下几个类:

LocalDate:表示日期,不包含时间信息。
LocalTime:表示时间,不包含日期信息。
LocalDateTime:表示日期和时间,不包含时区信息。
ZonedDateTime:表示带时区的日期和时间。
Instant:表示时间戳。
Duration:表示时间间隔。
Period:表示日期间隔。
SimpleDateFormat:SimpleDateFormat类用于格式化日期,将日期对象转换为指定格式的字符串,或将字符串解析为日期对象。

import java.util.Date;
import java.util.Calendar;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

// 使用Date类(已废弃)
Date date = new Date();
System.out.println("Current date (Date): " + date);

// 使用Calendar类
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1; // 月份从0开始计算,需要加1
int day = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println("Current date (Calendar): " + year + "-" + month + "-" + day);

// 使用新的日期时间API
LocalDate localDate = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String formattedDate = localDate.format(formatter);
System.out.println("Current date (LocalDate): " + formattedDate);

注意事项

避免使用过时的类和方法:尽量避免使用已过时的类和方法,因为它们可能存在性能问题或安全漏洞。始终优先选择最新的API和类。

处理异常:对可能抛出异常的代码进行适当的异常处理,以确保程序稳定性。可以使用try-catch块或throws关键字将异常传播出去。

注意线程安全:某些类(如StringBuilder)是非线程安全的,如果在多线程环境下使用,可能会导致意外结果。在多线程环境下,请考虑使用线程安全的替代类,或者使用同步机制保证线程安全。

正确释放资源:对于需要手动关闭的资源(如文件、数据库连接等),务必在使用完毕后及时关闭,以避免资源泄漏。

使用合适的集合类:根据需求选择合适的集合类,如ArrayList、LinkedList、HashMap等,以提高代码的效率和可读性。

注意对象的比较:在比较对象时,要注意使用equals()方法而不是"==" 符号, 因为" =="比较的是对象的引用是否相同,而equals()比较的是对象的内容是否相同。