(九)Java Object类的使用全面解析
一、Object类概述
1.1 Object类在Java中的地位
在Java语言中,Object类是所有类的超类,位于类继承树的顶端。它是Java类层次结构中的根类,每个类都直接或间接继承自Object类。当我们定义一个类时,如果没有明确使用extends关键字指定父类,Java编译器会自动让这个类继承Object类。
java
public class MyClass {// 即使没有显式继承,实际上相当于 public class MyClass extends Object
}
1.2 Object类的定义与位置
Object类位于java.lang包中,这是Java的核心包之一,无需显式导入即可使用。它的完整定义如下:
java
public class Object {// 类的方法实现
}
由于所有类都继承自Object,因此Object类中定义的方法对所有对象都可用。理解Object类的方法对于编写高质量的Java代码至关重要。
1.3 Object类的主要方法概览
Object类提供了以下主要方法,这些方法构成了Java对象的基本行为:
-
public final native Class<?> getClass()
-
public native int hashCode()
-
public boolean equals(Object obj)
-
protected native Object clone() throws CloneNotSupportedException
-
public String toString()
-
public final native void notify()
-
public final native void notifyAll()
-
public final native void wait(long timeout) throws InterruptedException
-
public final void wait(long timeout, int nanos) throws InterruptedException
-
public final void wait() throws InterruptedException
-
protected void finalize() throws Throwable
(Java 9后已弃用)
这些方法可以分为几类:对象基本信息方法(hashCode, equals, toString, getClass)、线程通信方法(wait, notify, notifyAll)、对象复制方法(clone)和垃圾回收相关方法(finalize)。
二、对象基本信息方法
2.1 getClass()方法详解
getClass()
方法返回对象的运行时类,这是一个final方法,不能被重写。它返回一个Class对象,该对象包含了与类相关的元数据信息。
java
public class GetClassExample {public static void main(String[] args) {String str = "Hello";Class<?> strClass = str.getClass();System.out.println("Class name: " + strClass.getName());System.out.println("Simple name: " + strClass.getSimpleName());System.out.println("Is interface: " + strClass.isInterface());}
}
输出结果:
Class name: java.lang.String Simple name: String Is interface: false
getClass()方法常用于反射操作,通过Class对象可以获取类的构造方法、字段、方法等信息,实现动态创建对象、调用方法等功能。
2.2 hashCode()方法与对象哈希值
hashCode()
方法返回对象的哈希码值,这是一个native方法,其实现通常基于对象的内存地址。哈希码的主要用途是在哈希表(如HashMap、HashSet)中快速定位对象。
hashCode()方法的通用约定:
-
在Java应用程序执行期间,对同一对象多次调用hashCode()方法必须返回相同的整数,前提是对象用于比较的信息没有被修改
-
如果两个对象通过equals(Object)方法比较是相等的,那么它们的hashCode()方法必须产生相同的整数结果
-
如果两个对象通过equals(Object)方法比较是不相等的,不要求它们的hashCode()方法必须产生不同的结果
java
public class HashCodeExample {public static void main(String[] args) {String s1 = "Hello";String s2 = "Hello";String s3 = "World";System.out.println(s1.hashCode()); // 69609650System.out.println(s2.hashCode()); // 69609650System.out.println(s3.hashCode()); // 83766130}
}
2.3 equals()方法与对象相等性
equals()
方法用于比较两个对象是否"相等"。Object类中的默认实现是比较两个对象的内存地址:
java
public boolean equals(Object obj) {return (this == obj);
}
在实际应用中,我们通常需要重写equals()方法来实现业务逻辑上的相等性比较。重写equals()方法时需要遵循以下原则:
-
自反性:x.equals(x)必须返回true
-
对称性:x.equals(y)必须与y.equals(x)返回相同结果
-
传递性:如果x.equals(y)返回true且y.equals(z)返回true,那么x.equals(z)必须返回true
-
一致性:只要对象没有修改,多次调用equals()方法必须返回相同结果
-
非空性:x.equals(null)必须返回false
java
public class Person {private String name;private int age;@Overridepublic boolean equals(Object obj) {if (this == obj) return true;if (obj == null || getClass() != obj.getClass()) return false;Person person = (Person) obj;return age == person.age && Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}
2.4 toString()方法与对象字符串表示
toString()
方法返回对象的字符串表示形式,对于调试和日志记录非常有用。Object类中的默认实现是:
java
public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
这通常会返回类似"com.example.MyClass@1b6d3586"的字符串。在实际应用中,我们通常会重写toString()方法以提供更有意义的信息:
java
public class Person {private String name;private int age;@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}
良好的toString()实现应该:
-
包含类的重要字段信息
-
格式清晰易读
-
不包含敏感信息
-
保持一致性(多次调用返回相同结果)
三、对象克隆与复制
3.1 clone()方法的基本使用
clone()
方法用于创建并返回对象的一个副本。Object类中的clone()方法是protected的,需要类显式重写并公开该方法才能使用。
java
protected native Object clone() throws CloneNotSupportedException;
要使用clone()方法,类必须实现Cloneable接口,否则会抛出CloneNotSupportedException。Cloneable是一个标记接口,不包含任何方法。
java
public class CloneExample implements Cloneable {private int[] data;public CloneExample() {data = new int[]{1, 2, 3, 4, 5};}@Overridepublic CloneExample clone() throws CloneNotSupportedException {return (CloneExample) super.clone();}public void displayData() {System.out.println(Arrays.toString(data));}public void modifyData() {data[0] = 100;}
}
3.2 浅拷贝与深拷贝的概念
Object.clone()方法执行的是浅拷贝,即只复制对象本身和其基本类型字段,对于引用类型的字段,只复制引用而不复制引用的对象。
java
public class ShallowCopyExample {public static void main(String[] args) throws CloneNotSupportedException {CloneExample original = new CloneExample();CloneExample cloned = original.clone();original.displayData(); // [1, 2, 3, 4, 5]cloned.displayData(); // [1, 2, 3, 4, 5]cloned.modifyData();original.displayData(); // [100, 2, 3, 4, 5]cloned.displayData(); // [100, 2, 3, 4, 5]}
}
要实现深拷贝,需要手动复制所有可变对象:
java
public class DeepCopyExample implements Cloneable {private int[] data;public DeepCopyExample() {data = new int[]{1, 2, 3, 4, 5};}@Overridepublic DeepCopyExample clone() throws CloneNotSupportedException {DeepCopyExample cloned = (DeepCopyExample) super.clone();cloned.data = data.clone(); // 复制数组return cloned;}// 其他方法同上
}
3.3 实现深拷贝的几种方式
除了重写clone()方法实现深拷贝外,还有以下几种方式:
-
使用构造方法复制:
java
public Person(Person original) {this.name = original.name;this.age = original.age;// 对于引用类型需要创建新对象
}
-
使用序列化/反序列化:
java
public static <T extends Serializable> T deepCopy(T object) {try {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(object);ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);return (T) ois.readObject();} catch (Exception e) {throw new RuntimeException(e);}
}
-
使用第三方库:如Apache Commons Lang的SerializationUtils.clone()方法
3.4 clone()方法的替代方案
由于clone()方法存在一些问题(如浅拷贝、需要实现Cloneable接口、clone()方法是protected的等),许多专家建议使用其他方式实现对象复制:
-
复制工厂方法:
java
public static Person newInstance(Person other) {return new Person(other.getName(), other.getAge());
}
-
使用Builder模式:
java
Person copy = Person.builder().name(original.getName()).age(original.getAge()).build();
-
使用映射工具:如MapStruct、Dozer等对象映射工具
四、线程通信方法
4.1 wait(), notify(), notifyAll()方法的作用
这三个方法用于线程间的协调通信,必须在同步代码块或同步方法中调用:
-
wait()
:使当前线程等待,直到其他线程调用notify()或notifyAll()方法,或指定的超时时间到达 -
notify()
:唤醒在此对象监视器上等待的单个线程 -
notifyAll()
:唤醒在此对象监视器上等待的所有线程
java
public class WaitNotifyExample {private boolean flag = false;public synchronized void waitForFlag() throws InterruptedException {while (!flag) {wait(); // 释放锁并等待}System.out.println("Flag is now true");}public synchronized void setFlag() {this.flag = true;notifyAll(); // 唤醒所有等待线程}
}
4.2 生产者-消费者模式实现
经典的线程间通信示例:
java
public class ProducerConsumerExample {private final Queue<Integer> queue = new LinkedList<>();private final int capacity;public ProducerConsumerExample(int capacity) {this.capacity = capacity;}public synchronized void produce(int value) throws InterruptedException {while (queue.size() == capacity) {wait(); // 队列满,等待}queue.add(value);System.out.println("Produced: " + value);notifyAll(); // 通知消费者}public synchronized int consume() throws InterruptedException {while (queue.isEmpty()) {wait(); // 队列空,等待}int value = queue.poll();System.out.println("Consumed: " + value);notifyAll(); // 通知生产者return value;}
}
4.3 使用注意事项与常见问题
-
虚假唤醒:wait()方法可能在未被通知的情况下返回,因此应该总是在循环中检查等待条件
-
丢失唤醒:如果在notify()调用时没有线程在等待,通知会丢失,因此正确设置状态变量很重要
-
同步范围:wait()和notify()必须在同步块内调用,否则会抛出IllegalMonitorStateException
-
优先使用notifyAll():notify()只唤醒一个线程,可能不是你想要唤醒的线程,而notifyAll()更安全但性能稍低
五、finalize()方法与垃圾回收
5.1 finalize()方法的原始设计目的
finalize()
方法在对象被垃圾回收器回收之前调用,设计初衷是让对象有机会清理资源。Object类中的实现为空:
java
protected void finalize() throws Throwable { }
5.2 finalize()方法的执行机制
-
当垃圾回收器确定没有更多引用指向对象时,会将该对象标记为可回收
-
在对象被实际回收前,如果它重写了finalize()方法,则将该对象放入一个特殊的队列
-
一个低优先级的Finalizer线程会逐个调用这些对象的finalize()方法
-
finalize()方法执行后,对象会被再次标记,如果此时仍然不可达,则在下一次GC时被回收
java
public class FinalizeExample {private String name;public FinalizeExample(String name) {this.name = name;}@Overrideprotected void finalize() throws Throwable {try {System.out.println("Finalizing " + name);} finally {super.finalize();}}public static void main(String[] args) {new FinalizeExample("example");System.gc(); // 提示JVM执行垃圾回收,但不保证立即执行}
}
5.3 finalize()方法的缺陷与替代方案
finalize()方法存在严重问题:
-
执行时间不确定:无法保证何时被调用,甚至可能永远不会被调用
-
性能开销:延长对象生命周期,增加GC负担
-
异常处理:finalize()中抛出异常会导致处理终止且不报告
-
安全问题:可能被恶意代码利用复活对象
Java 9开始,finalize()方法被标记为@Deprecated。替代方案包括:
-
try-with-resources:对于AutoCloseable资源
java
try (Resource resource = new Resource()) {// 使用资源
} // 自动调用close()
-
Cleaner和PhantomReference:Java 9引入的更灵活的清理机制
java
public class CleanerExample implements AutoCloseable {private static final Cleaner cleaner = Cleaner.create();private final Cleaner.Cleanable cleanable;private final Resource resource;public CleanerExample() {this.resource = new Resource();this.cleanable = cleaner.register(this, resource::clean);}@Overridepublic void close() {cleanable.clean();}private static class Resource {void clean() {// 清理逻辑}}
}
六、Object类的最佳实践
6.1 正确重写equals()和hashCode()方法
遵循以下规则:
-
总是同时重写equals()和hashCode()方法
-
使用相同的字段集合计算hashCode()和equals()比较
-
考虑使用Objects工具类简化实现
-
对于可变对象,确保hashCode()值在对象生命周期内保持一致
java
@Override
public boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;MyClass myClass = (MyClass) o;return Objects.equals(field1, myClass.field1) &&Objects.equals(field2, myClass.field2);
}@Override
public int hashCode() {return Objects.hash(field1, field2);
}
6.2 实现有意义的toString()方法
好的toString()实现应该:
-
包含足够的信息以识别对象状态
-
格式一致且易于解析
-
避免包含敏感信息
-
考虑使用自动生成工具(如IDE生成或ToStringBuilder)
java
@Override
public String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", address=" + address +'}';
}
6.3 谨慎使用clone()方法
-
考虑是否真的需要clone(),或者是否可以通过其他方式实现对象复制
-
如果实现clone(),确保正确处理深拷贝
-
考虑使用复制构造方法或静态工厂方法替代
-
文档化clone()方法的实现细节
6.4 避免使用finalize()方法
-
对于资源清理,优先使用try-with-resources
-
对于必须的清理操作,考虑使用Cleaner API
-
如果必须使用finalize(),确保调用super.finalize()并处理异常
七、Object类在Java集合框架中的应用
7.1 HashMap与hashCode()/equals()的关系
HashMap使用hashCode()确定桶的位置,使用equals()解决哈希冲突:
java
public class HashMapKeyExample {static class Key {private int id;public Key(int id) {this.id = id;}// 故意不重写hashCode和equals}public static void main(String[] args) {Map<Key, String> map = new HashMap<>();Key k1 = new Key(1);Key k2 = new Key(1);map.put(k1, "Value 1");System.out.println(map.get(k2)); // null,因为k1和k2被认为是不同的键}
}
7.2 HashSet如何判断元素唯一性
HashSet内部使用HashMap实现,同样依赖hashCode()和equals()方法:
java
public class HashSetExample {public static void main(String[] args) {Set<Person> set = new HashSet<>();Person p1 = new Person("Alice", 25);Person p2 = new Person("Alice", 25);set.add(p1);set.add(p2);System.out.println(set.size()); // 如果Person正确重写了hashCode和equals,输出1}
}
7.3 TreeSet/TreeMap与Comparable/Comparator
TreeSet和TreeMap使用元素的自然顺序(Comparable)或比较器(Comparator)来维护顺序:
java
public class Person implements Comparable<Person> {private String name;private int age;@Overridepublic int compareTo(Person other) {int nameCompare = this.name.compareTo(other.name);if (nameCompare != 0) {return nameCompare;}return Integer.compare(this.age, other.age);}// equals和hashCode等其他方法
}
八、Java 8后Object类的新增方法
8.1 Objects工具类的实用方法
Java 7引入了java.util.Objects工具类,提供了一系列静态方法来操作对象:
-
Objects.equals(Object a, Object b)
:安全的null相等比较 -
Objects.hash(Object... values)
:生成哈希码 -
Objects.requireNonNull(T obj)
:检查非null -
Objects.toString(Object o, String nullDefault)
:安全的toString
java
public class ObjectsExample {public static void main(String[] args) {String str1 = null;String str2 = "Hello";System.out.println(Objects.equals(str1, str2)); // falseSystem.out.println(Objects.hash(str1, str2)); // 基于值的哈希码System.out.println(Objects.toString(str1, "null value")); // "null value"// Objects.requireNonNull(str1); // 抛出NullPointerException}
}
8.2 默认方法冲突与Object方法
Java 8引入默认方法后,接口可以提供方法实现。但接口不能重写Object类的方法:
java
public interface MyInterface {default boolean equals(Object obj) { // 编译错误return false;}default String toString() { // 编译错误return "Interface";}// 合法,因为Object没有hash方法default int hash() {return 42;}
}
九、常见面试问题与解答
9.1 equals()与==的区别
-
==
是运算符,用于比较基本类型的值或引用类型的引用地址 -
equals()
是方法,用于比较对象的内容(需要正确重写)
java
String s1 = new String("Hello");
String s2 = new String("Hello");System.out.println(s1 == s2); // false,不同对象
System.out.println(s1.equals(s2)); // true,内容相同
9.2 hashCode()与equals()的契约
必须满足:
-
一致性:对象不变时,hashCode()应返回相同值
-
相等性:如果equals()返回true,hashCode()必须相同
-
不等性:equals()返回false时,hashCode()可以相同(哈希冲突)
9.3 clone()方法的深拷贝与浅拷贝
-
浅拷贝:复制对象及其基本类型字段,引用类型字段只复制引用
-
深拷贝:复制对象及其所有引用的对象,形成完全独立的副本
9.4 finalize()为什么不推荐使用
-
执行时间不确定
-
性能开销大
-
可能导致资源泄漏
-
安全问题
-
Java 9已标记为@Deprecated
9.5 wait()和sleep()的区别
特性 | wait() | sleep() |
---|---|---|
所属类 | Object | Thread |
释放锁 | 是 | 否 |
唤醒方式 | notify()/notifyAll()或超时 | 仅超时 |
调用要求 | 必须在同步块中 | 可以在任何地方 |
用途 | 线程间协调 | 暂停当前线程 |
十、总结与展望
Object类作为Java类体系的根基,提供了对象的基本行为规范。理解并正确使用Object类的方法对于编写健壮、高效的Java程序至关重要。随着Java语言的发展,Object类的一些方法(如finalize())已被标记为过时,而新的API(如Cleaner)被引入以提供更好的解决方案。
未来,Java可能会继续优化对象的基本行为,但Object类的核心方法(equals、hashCode、toString等)仍将是Java编程的基础。掌握这些方法的使用原则和最佳实践,是每个Java开发者必备的技能。
相关文章:
(九)Java Object类的使用全面解析
一、Object类概述 1.1 Object类在Java中的地位 在Java语言中,Object类是所有类的超类,位于类继承树的顶端。它是Java类层次结构中的根类,每个类都直接或间接继承自Object类。当我们定义一个类时,如果没有明确使用extends关键字指…...

LVGL对象(Objects)
文章目录 🧱 一、LVGL 中的对象(lv\_obj)🔹 lv\_obj\_t 的作用 🧩 二、对象的分类结构(类比继承)🧰 三、对象的创建与销毁✅ 创建对象示例:创建一个按钮❌ 删除对象 &…...
自然语言到 SQL 转换:开启智能数据库交互新时代
引言 随着人工智能技术的飞速发展,自然语言处理(NLP)领域取得了显著的进步。其中,将自然语言转换为 SQL 语句的技术尤为引人注目。这种技术能够帮助用户,尤其是那些不熟悉 SQL 的业务人员,快速从数据库中获…...

服务器配置错误导致SSL/TLS出现安全漏洞,如何进行排查?
SSL/TLS 安全漏洞排查与修复指南 一、常见配置错误类型 弱加密算法与密钥问题 使用弱密码套件(如DES、RC4)或密钥长度不足(如RSA密钥长度<2048位),导致加密强度不足。 密钥管理不当(如私钥未加密存…...

路由重发布
路由重发布 实验目标: 掌握路由重发布的配置方法和技巧; 掌握通过路由重发布方式实现网络的连通性; 熟悉route-pt路由器的使用方法; 实验背景:假设学校的某个分区需要配置简单的rip协议路由信息,而主校…...

C++修炼:stack和queue
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路! 我的博客:<但凡. 我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 欢迎点赞,关注&am…...
【软件工程】基于频谱的缺陷定位
基于频谱的缺陷定位(Spectrum-Based Fault Localization, SBFL)是一种通过分析程序执行覆盖信息(频谱数据)来定位代码中缺陷的方法。其核心思想是:通过测试用例的执行结果(成功/失败)和代码覆盖…...

【计算机视觉】优化MVSNet可微分代价体以提高深度估计精度的关键技术
优化MVSNet可微分代价体以提高深度估计精度的关键技术 1. 代价体基础理论与分析1.1 标准代价体构建1.2 关键问题诊断 2. 特征表示优化2.1 多尺度特征融合2.2 注意力增强匹配 3. 代价体构建优化3.1 自适应深度假设采样3.2 可微分聚合操作改进 4. 正则化与优化策略4.1 多尺度代价…...
为什么tcp不能两次握手
TCP **不能用“两次握手”**的根本原因是:两次握手无法确保双方“都知道”连接是可靠建立的,容易引发“旧连接请求”造成错误连接。 🔁 先看标准的 三次握手(3-Way Handshake)流程 客户端 服务器| …...
常见音频主控芯片以及相关厂家总结
音频主控芯片是音频设备(如蓝牙耳机、音箱、功放等)的核心组件,负责音频信号的解码、编码、处理和传输。以下是常见的音频主控芯片及其相关厂家,按应用领域分类: 蓝牙音频芯片 主要用于无线耳机、音箱等设备࿰…...
掌握 Kubernetes 和 AKS:热门面试问题和专家解答
1. 在 AKS(Azure Kubernetes 服务)中,集群、节点、Pod 和容器之间的关系和顺序是什么? 在 AKS(Azure Kubernetes 服务)中,集群、节点、Pod 和容器之间的关系和顺序如下: 集群&#…...
【MyBatis-7】深入理解MyBatis二级缓存:提升应用性能的利器
在现代应用开发中,数据库访问往往是性能瓶颈之一。作为Java生态中广泛使用的ORM框架,MyBatis提供了一级缓存和二级缓存机制来优化数据库访问性能。本文将深入探讨MyBatis二级缓存的工作原理、配置方式、使用场景以及最佳实践,帮助开发者充分利…...
5.9-selcct_poll_epoll 和 reactor 的模拟实现
5.9-select_poll_epoll 本文演示 select 等 io 多路复用函数的应用方法,函数具体介绍可以参考我过去写的博客。 先绑定监听的文件描述符 int sockfd socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(struc…...
《算法导论(第4版)》阅读笔记:p17-p27
《算法导论(第4版)》学习第 10 天,p17-p27 总结,总计 11 页。 一、技术总结 1. insertion sort (1)keys The numbers to be sorted are also known as the keys(要排序的数称为key)。 第 n 次看插入排序,这次有两个地方感触比较深&#…...

软考错题集
一个有向图具有拓扑排序序列,则该图的邻接矩阵必定为()矩阵。 A.三角 B.一般 C.对称 D.稀疏矩阵的下三角或上三角部分包含非零元素,而其余部分为零。一般矩阵这个术语太过宽泛,不具体指向任何特定性 质的矩阵。对称矩阵…...

T2I-R1:通过语义级与图像 token 级协同链式思维强化图像生成
文章目录 速览摘要1 引言2 相关工作统一生成与理解的 LMM(Unified Generation and Understanding LMM.)用于大型推理模型的强化学习(Reinforcement Learning for Large Reasoning Models.)3 方法3.1 预备知识3.2 语义级与令牌级 CoT语义级 CoT(Semantic-level CoT)令牌级…...

Dockers部署oscarfonts/geoserver镜像的Geoserver
Dockers部署oscarfonts/geoserver镜像的Geoserver 说实话,最后发现要选择合适的Geoserver镜像才是关键,所以所以所以…🐷 推荐oscarfonts/geoserver的镜像! 一开始用kartoza/geoserver镜像一直提示内存不足,不过还好…...
【脑机接口临床】脑机接口手术的风险?脑机接口手术的应用场景?脑机接口手术如何实现偏瘫康复?
脑机接口的应用 通常对脑机接口感兴趣的两类人群,一类是适应症患者 ,另一类是科技爱好者。 1 意念控制外部设备 常见的外部设备有:外骨骼、机械手、辅助康复设备、电刺激设备、电脑光标、轮椅。 2 辅助偏瘫康复或辅助脊髓损伤患者意念控制…...

扩增子分析|微生物生态网络稳定性评估之鲁棒性(Robustness)和易损性(Vulnerability)在R中实现
一、引言 周集中老师团队于2021年在Nature climate change发表的文章,阐述了网络稳定性评估的原理算法,并提供了完整的代码。自此对微生物生态网络的评估具有更全面的指标,自此网络稳定性的评估广受大家欢迎。本系列将介绍网络稳定性之鲁棒性…...
Client 和 Server 的关系理解
client.py 和 server.py 是基于 MCP(Multi-Component Protocol)协议的客户端-服务端架构,二者的关系如下: 1. 角色分工 server.py:服务端,负责注册和实现各种“工具函数”(如新闻检索、情感分…...

【含文档+PPT+源码】基于微信小程序的社区便民防诈宣传系统设计与实现
项目介绍 本课程演示的是一款基于微信小程序的社区便民防诈宣传系统设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套…...
Kafka的核心组件有哪些?简要说明其作用。 (Producer、Consumer、Broker、Topic、Partition、ZooKeeper)
Kafka 核心组件解析 1. 基础架构图解 ┌─────────┐ ┌─────────┐ ┌─────────┐ │Producer │───▶ │ Broker │ ◀─── │Consumer │ └─────────┘ └─────────┘ └────────…...
Java中对象集合转换的优雅实现【实体属性范围缩小为vo】:ListUtil.convert方法详解
1.业务场景 在开发电商系统时,我们经常需要处理订单信息的展示需求。例如:订单详情页需要显示退款信息列表,而数据库中存储的RefundInfo实体类包含敏感字段,直接返回给前端存在安全风险。此时就需要将RefundInfo对象集合转换为Or…...

【MySQL】存储引擎 - ARCHIVE、BLACKHOLE、MERGE详解
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...

代码随想录第41天:图论2(岛屿系列)
一、岛屿数量(Kamacoder 99) 深度优先搜索: # 定义四个方向:右、下、左、上,用于 DFS 中四向遍历 direction [[0, 1], [1, 0], [0, -1], [-1, 0]]def dfs(grid, visited, x, y):"""对一块陆地进行深度…...
Vue插槽(Slots)详解
文章目录 1. 插槽简介1.1 什么是插槽?1.2 为什么需要插槽?1.3 插槽的基本语法 2. 默认插槽2.1 什么是默认插槽?2.2 默认插槽语法2.3 插槽默认内容2.4 默认插槽实例:创建一个卡片组件2.5 Vue 3中的默认插槽2.6 默认插槽的应用场景 …...
中国古代史1
朝代歌 三皇五帝始,尧舜禹相传。 夏商与西周,东周分两段。 春秋和战国,一统秦两汉。 三分魏蜀吴,二晋前后延。 南北朝并立,隋唐五代传。 宋元明清后,皇朝至此完。 原始社会 元谋人,170万年前…...
vue +xlsx+exceljs 导出excel文档
实现功能:分标题行导出数据过多,一个sheet表里表格条数有限制,需要分sheet显示。 步骤1:安装插件包 npm install exceljs npm install xlsx 步骤2:引用包 import XLSX from xlsx; import ExcelJS from exceljs; 步骤3&am…...
nginx之proxy_redirect应用
一、功能说明 proxy_redirect 是 Nginx 反向代理中用于修改后端返回的响应头中 Location 和 Refresh 字段的核心指令,主要解决以下问题:协议/地址透传错误:当后端返回的 Location 包含内部 IP、HTTP 协议或非标准端口时,需修正为…...
在 Flink + Kafka 实时数仓中,如何确保端到端的 Exactly-Once
在 Flink Kafka 构建实时数仓时,确保端到端的 Exactly-Once(精确一次) 需要从 数据消费(Source)、处理(Processing)、写入(Sink) 三个阶段协同设计,结合 Fli…...