【JAVA BASE API】介绍Java基础API语法,包括JAVA8之后的时间日期等

简介: 【JAVA BASE API】介绍Java基础API语法,包括JAVA8之后的时间日期等


Object 类

Object类是类层次结构的根。每个类都有 Object作为超类。所有对象,包括数组,实现这个类的方法

Object 常见的 API

API 用法
clone() 创建并返回此对象的副本
toString() 返回对象的字符串表现形式
equals(Object obj) 指示是否有其他对象 “等于” 这一个

clone 对象克隆

public class Demo{
  public static void main(String[] args) {
  Person p = new Person(12, "zhangssan");
  Person p1 = null;
  {
    try{
    p1 = (Person)p.clone();
    } catch(CloneNotSupportedException e) {
    e.printStackTrace();
    }
  {
  System.out.println(p); // Person@123456
  System out.println(p1); // Person@114514
  }
}

从这边代码可以看到 p1 使用 clone 方法 克隆 对象 p

地址却是不一样的, 说明我们开辟了一块新的栈内存

浅拷贝 与 深拷贝

  1. 浅拷贝
// Person 类
class Person implements Cloneable {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override             // throws xxx 异常声明 或使用 try catch
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}
// Main 程序入口类
public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("Alice", 25);
        Person person2 = (Person) person1.clone();
        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
        // 修改person1的字段
        person1.setName("Bob");
        person1.setAge(30);
        // 验证浅拷贝的效果
        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
    }
}
  1. 只可以在子类中重写克隆方法, 因为 Main 函数不是类的实例方法, 它无法被继承或重写
  2. 可以看到 Person 类实现了一个接口 Cloneable, 这个 Cloneable 就称之为 标记接口, 它表示该类的实例可以被克隆, 看开看你会发现它只是一个 …{}

运行如下

person1: Person{name='Alice', age=25}
person2: Person{name='Alice', age=25}
person1: Person{name='Bob', age=30}
person2: Person{name='Alice', age=25}
  1. 深拷贝
// Person 类
class Person implements Cloneable {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override         // throws xxx 异常声明 或使用 try catch
    public Object clone() throws CloneNotSupportedException {
        // 创建新的Person对象
        Person clonedPerson = (Person) super.clone();
        // 修改为深拷贝
        clonedPerson.name = new String(this.name);
        // 对于基本类型,直接复制值
        clonedPerson.age = this.age;
        return clonedPerson;
    }
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}
// Main 程序入口类
public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("Alice", 25);
        Person person2 = (Person) person1.clone();
        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
        // 修改person1的字段
        person1.setName("Bob");
        person1.setAge(30);
        // 验证深拷贝的效果
        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
    }
}

运行如下

person1: Person{name='Alice', age=25}
person2: Person{name='Alice', age=25}
person1: Person{name='Bob', age=30}
person2: Person{name='Alice', age=25}

首先,创建了一个名为 person1Person 对象,其姓名为 "Alice",年龄为 25 然后,通过调用clone() 方法创建了一个名为 person2 的新对象,它与 person1 具有相同的属性值。

在验证深拷贝效果之前,我们修改了 person1 的姓名为 "Bob" ,年龄为 30 最后,输出了 person1person2 的详细信息。

可以看到,person1 的改变没有影响到 person2 ,说明这是一个深拷贝。因此,person1 被成功拷贝到了 person2 它们之间没有共享字段的引用。

toString() 转换字符串

toString() 方法源码

public String toString() {
   return "Person{name='" + name + "', age=" + age + "}"; // 例如有name age字段
}

使用

// 入口函数 Main
public class Main {
    public static void main(String[] args) {
        Person person = new Person("John", 25);
        System.out.println(person.toString());
    }
}

输出: Person{name=“John”, age=25}

equals(Object obj) 地址比较

简单比较两个对象的引用

Object obj1 = new Object();
Object obj2 = obj1;
if (obj1 == obj2) {
    // 两个对象的引用相等
}

判断两个对象的地址是否相等

obj1.equals(obj2);

Objects 类

Objects是一个工具类,提供了很多操作对象的静态方法给我们使用

它与 Object 类有着相同的方法名,功能都是类似的

Objects.equals(Object obj1, Object obj2) 非空比较

Objects.equals 先做非空判断,再做对象比较

源码解析

public static boolean equals(Object a, Object b) {
    return (a == b) || (a != null && a.equals(b));
}

isNull(Object obj) 判断null

判断对象是否为 null 若为 null 返回 true

nonNull(Object obj) 判断非null

判断对象是否不为 null 若不为 null 返回 true

包装类

基本数据类型对应的包装类列表

基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
char Character
float Float
double Double
boolean Boolean

自动装箱

可以自动把基本类型的数据转换成对象

例如

Integer a1 = 12;

自动拆箱

可以自动把包装类型的对象转换成对应基本数据类型

例如

int a4 = a1;

字符串操作 | StringBuilder,StringBuffer,StringJoiner

StringBuilderStringBufferStringJoiner 都是一些字符串的操作方法,它们有时比 String 更适合做字符串的修改操作,效率也会更高,代码也会更简洁

StringBuilder 字符串操作

StringBuilder 在操作字符串的时候效率非常高(频繁拼接,修改建议使用 StringBuilder )

基本使用

StringBuilder s = new StringBuilder();
StringBuilder s = new StringBuilder("hello");
// 拼接内容
s.append(12);
s.append("hi");
s.append(true);
// 返回内容: “hello12hitrue”
// 支持链式编程
s.append(true).append("haha")

使用 StringBuilder 拼接数组

public static void main(String[] args) {
  System.out.println(getArrayList(new int[] {
      1, 123, 456
  }));
}
// 实现方法
public static String getArrayList(int[] arr) {
    if (arr == null) {
        return null;
    }
  // 实例化字符串操作类 StringBuilder
    StringBuilder sb = new StringBuilder();
    sb.append("[");
    for (int i = 0; i < arr.length; i++) {
      if (i == arr.length - 1) { // 若拼接到最后一个不加 ,
        sb.append(arr[i]);
      } else {
        sb.append(arr[i]).append(",");
      }
  }
  sb.append("]");
  return sb.toString(); // 返回 字符串表现形式
}

StringBuffer 字符串操作

StringBuilder 相似,但是 StringBuilder 是线程不安全的,StringBuffer 是线程安全的

StringJoiner 字符串拼接

StringBuilder 相似,也是用来操作字符串的,也可以看成是一个容器,创建之后里面的内容是可变的

好处: 不仅能提高字符串的操作效率,并且在有些场景下使用它操作字符串,代码会更简洁

基本使用

StringJoiner s = new StringJoiner(间隔符号);
StringJoiner s = new StringJoiner(间隔符号, 开始符号, 结束符号);

StringJoiner 相对于 StringBuilder 来说还是比较简单, 一般只可以操作简单的字符拼接,如果需要频繁插入,删除字符,建议使用 StringBuilder 操作

StringJoiner s = new StringJoiner(", ");
s.add("java1");
s.add("java2"); 
// java1, java2
// ----------------------------------
StringJoiner s = new StringJoiner(", ", "[", "]");
s.add("java1");
s.add("java2"); 
// [java1, java2]

使用 StringJoiner 拼接

public static void main(String[] args) {
  System.out.println(getArrayData(new int[] {
      1, 2, 3
  }));
}
public static string getArrayData(int[] arr) {
  // 判断 arr 非空
  if (arr == null) {
    return null;
  }
  // arr 数组存在
  StringJoiner sj = new StringJoiner(", ", "[", "]");
  for(int i = 0; i < arr.length; i++) {
    sj.add(arr[i] + "");
  }
  return sj.toString();
}

MathSystemRuntime

Math 数学类

Math 代表数学,是一个工具类,里面提供的都是对数据进行操作的一些静态方法

System 系统类

System.currentTimeMillis(); // 获取当前系统的时间(毫秒值) long 类型

Runtime 运行类

小知识: Runtime 是个单例设计模式的类

简单使用

Runtime r = Runtime.getRuntime(); // 返回与当前Java应用程序关联的运行时对象

BigDecimal 解决小数失真运算

在一些商业项目中,在进行一些小数运算时,必须要求精准,使用传统运算符时可能会出现小数运算失真的情况

System.out.println(0.2 + 0.1); // 0.30000000000000004

采用 java.util.math 中的 BigDecimal 类 来运算解决失真问题

// 转为 字符串 封装成 BigDecimal 对象来运算
BigDecimal a1 = new BigDecimal(Double.toString(a));
BigDecimal b1 = new BigDecimal(Double.toString(b));
// 优化
// 推荐用以下方式把小数转换为字符串再得到BigDecimal对象来使用(更简洁)
BigDecimal a1 = BiDecimal.valueOf(a);
BigDecimal b1 = BiDecimal.valueOf(b);
BigDecimal b = a1.add(b1);
BigDecimal b = a1.subtract(b1);
BigDecimal b = a1.multiply(b1);
BigDecimal b = a1.divide(b1);

Date 类

before Java 1.8

在 Java 1.8 之前,Date 对象是可变的,所以处理时间类需要谨慎

创建时间对象(部分过时)

Date currentDate = new Date(); // 使用当前日期和时间创建Date对象
Date specificDate = new Date(year, month, day); // 使用指定的年、月、日创建Date对象(过时的)

获取日期和时间(过时的)

int year = date.getYear(); // 获取年份(从1900年开始计算)
int month = date.getMonth(); // 获取月份(从0开始计算,0表示一月)
int day = date.getDate(); // 获取天数(月份中的日期)
int hours = date.getHours(); // 获取小时w
int minutes = date.getMinutes(); // 获取分钟
int seconds = date.getSeconds(); // 获取秒钟

设置日期和时间(过时的)

date.setYear(year); // 设置年份
date.setMonth(month); // 设置月份
date.setDate(day); // 设置天数
date.setHours(hours); // 设置小时
date.setMinutes(minutes); // 设置分钟
date.setSeconds(seconds); // 设置秒钟

格式化和解析时间对象(部分过时)

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 生成规定格式的时间对象(过时的)
String formattedDate = formatter.format(date); // 格式化Date对象为指定格式的字符串
Date parsedDate = formatter.parse("2022-01-01 12:00:00"); // 将字符串解析为Date对象

after Java 1.8


相关文章
|
5天前
|
Java 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
24 0
|
2天前
|
缓存 安全 Java
java面试-基础语法与面向对象
本文介绍了 Java 编程中的几个核心概念。首先,详细区分了方法重载与重写的定义、发生阶段及规则;其次,分析了 `==` 与 `equals` 的区别,强调了基本类型和引用类型的比较方式;接着,对比了 `String`、`StringBuilder` 和 `StringBuffer` 的特性,包括线程安全性和性能差异;最后,讲解了 Java 异常机制,包括自定义异常的实现以及常见非检查异常的类型。这些内容对理解 Java 面向对象编程和实际开发问题解决具有重要意义。
37 15
|
1天前
|
缓存 监控 负载均衡
如何提升 API 性能:来自 Java 和测试开发者的优化建议
本文探讨了如何优化API响应时间,提升用户体验。通过缓存(如Redis/Memcached)、减少数据负载(REST过滤字段或GraphQL精确请求)、负载均衡(Nginx/AWS等工具)、数据压缩(Gzip/Brotli)、限流节流、监控性能(Apipost/New Relic等工具)、升级基础设施、减少第三方依赖、优化数据库查询及采用异步处理等方式,可显著提高API速度。快速响应的API不仅让用户满意,还能增强应用整体性能。
|
5天前
|
设计模式 缓存 Java
重学Java基础篇—Java对象创建的7种核心方式详解
本文全面解析了Java中对象的创建方式,涵盖基础到高级技术。包括`new关键字`直接实例化、反射机制动态创建、克隆与反序列化复用对象,以及工厂方法和建造者模式等设计模式的应用。同时探讨了Spring IOC容器等框架级创建方式,并对比各类方法的适用场景与优缺点。此外,还深入分析了动态代理、Unsafe类等扩展知识及注意事项。最后总结最佳实践,建议根据业务需求选择合适方式,在灵活性与性能间取得平衡。
42 3
|
12天前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
41 11
|
5天前
|
安全 IDE Java
重学Java基础篇—Java泛型深度使用指南
本内容系统介绍了Java泛型的核心价值、用法及高级技巧。首先阐述了泛型在**类型安全**与**代码复用**中的平衡作用,解决强制类型转换错误等问题。接着详细讲解了泛型类定义、方法实现、类型参数约束(如边界限定和多重边界)、通配符应用(PECS原则)以及类型擦除的应对策略。此外,还展示了泛型在通用DAO接口、事件总线等实际场景的应用,并总结了命名规范、边界控制等最佳实践。最后探讨了扩展知识,如通过反射获取泛型参数类型。合理运用泛型可大幅提升代码健壮性和可维护性,建议结合IDE工具和单元测试优化使用。
12 1
|
5天前
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
18 1
|
9天前
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
1月前
|
数据采集 存储 Java
Java爬虫获取微店店铺所有商品API接口设计与实现
本文介绍如何使用Java设计并实现一个爬虫程序,以获取微店店铺的所有商品信息。通过HttpClient发送HTTP请求,Jsoup解析HTML页面,提取商品名称、价格、图片链接等数据,并将其存储到本地文件或数据库中。文中详细描述了爬虫的设计思路、代码实现及注意事项,包括反爬虫机制、数据合法性和性能优化。此方法可帮助商家了解竞争对手,为消费者提供更全面的商品比较。
|
9天前
|
运维 Cloud Native Java
postman发起post请求遇到报错:java.io.FileNotFoundException (文件名、目录名或卷标语法不正确。)
遇到bug报错,多猜可能的原因,控制变量反复测试,直至找到问题的关键,然后再思考如何解决或者回避。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来