当前位置: 首页 > web >正文

学习日志09 java

我要(ง •_•)ง!!

1 面向对象里面的编程的属性,其实就是变量啦

在面向对象编程里,“属性”(Attribute)也被叫做 “成员变量” 或者 “字段”(Field),指的是类中用来存储对象状态数据的变量。在这个题目里,Student类和Undergraduate类的属性分别如下:

Student类的属性

  • name:类型为String,用来存储学生的姓名。
  • age:类型为int,用来存储学生的年龄。

Undergraduate类的属性

  • 继承自Student类的属性:
    • name:存储本科生的姓名。
    • age:存储本科生的年龄。
  • 自身特有的属性:
    • major:类型为String,用来存储本科生的专业。

而题目中提到的show()方法,它的作用是输出对象的属性信息。也就是说,show()方法会把对象里各个属性的值组合成特定格式的字符串并返回。

代码示例说明属性与show()方法的关系

以下是结合你提供代码的简单说明:

Student

java

package PTA_training.Demo3_4;public class Student {protected String name;protected int age;public Student(String name, int age) {this.name = name;this.age = age;}public String show() {return "Student[name=" + name + ",age=" + age + "]";}
}

Student类中,nameage就是属性。show()方法将这两个属性的值组合成"Student[name=XXX,age=XX]"格式的字符串。

Undergraduate

java

package PTA_training.Demo3_4;public class Undergraduate extends Student {private String major;public Undergraduate(String name, int age, String major) {super(name, age);this.major = major;}public String show() {return "Undergraduate[name=" + name + ",age=" + age + ",major=" + major + "]";}
}

Undergraduate类中,除了继承自Student类的nameage属性,还有自身的major属性。show()方法会把这三个属性的值组合成"Undergraduate[name=XXX,age=XXX,major=XXX]"格式的字符串。

2 关于java里面的equals方法

在 Java 中,equals()方法是一个基础且重要的方法,主要用于比较两个对象是否相等。下面从多个方面对它进行详细介绍:

1. 方法定义

equals()方法在Object类中被定义,这意味着 Java 里的所有类都会继承该方法。其原始定义如下:

java

public boolean equals(Object obj) {return (this == obj);
}

可以看到,默认情况下,equals()方法比较的是两个对象的引用是否相同,也就是它们是否指向内存中的同一个对象。

2. 重写 equals () 方法

通常,我们需要根据对象的内容来判断它们是否相等,这时就需要重写equals()方法。比如:

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 && name.equals(person.name);}
}

3. 重写 equals () 的规范

在重写equals()方法时,需要遵循以下几个原则:

  • 自反性:对于任何非空引用值xx.equals(x)都应返回true
  • 对称性:若x.equals(y)返回true,那么y.equals(x)也应返回true
  • 传递性:若x.equals(y)true,且y.equals(z)true,那么x.equals(z)也应为true
  • 一致性:只要对象的关键属性没有改变,多次调用equals()方法应返回相同的结果。
  • 非空性:对于任何非空引用值xx.equals(null)应返回false

4. 与 "==" 的区别

  • ==:用于比较两个引用是否指向同一个对象,或者比较基本数据类型的值是否相等。
  • equals():在未被重写时,功能和==一样;重写后,可用于比较对象的内容是否相同。

5. 重写 equals () 时必须重写 hashCode ()

根据Object类的规范,如果两个对象通过equals()方法比较是相等的,那么它们的hashCode()返回值也必须相同。因此,重写equals()方法时,必须同时重写hashCode()方法,以保证这一规范的实现

java

@Override
public int hashCode() {return Objects.hash(name, age);
}

6. 常见错误

  • 未重写 equals ():直接使用默认的引用比较,可能无法满足业务需求。
  • 参数类型错误:若方法签名写成public boolean equals(Person other),这并不是对equals()方法的重写,而是定义了一个新方法。
  • 遗漏 null 或类型检查:可能会导致NullPointerException或比较逻辑出错。

7. 工具生成 equals ()

现代 IDE(如 IntelliJ IDEA、Eclipse)能够自动生成equals()hashCode()方法。此外,Lombok 库可以通过注解(如@EqualsAndHashCode)来自动生成这些方法。

8. 特殊类的 equals () 方法

  • 包装类(如 Integer、String):重写了equals()方法,用于比较对象的值。

    java

    Integer a = 1000;
    Integer b = 1000;
    System.out.println(a.equals(b)); // 输出true
    System.out.println(a == b);      // 输出false(装箱后的对象引用不同)
    
  • 数组:使用Arrays.equals()来比较数组内容,直接调用equals()比较的是引用。

    java

    int[] arr1 = {1, 2, 3};
    int[] arr2 = {1, 2, 3};
    System.out.println(arr1.equals(arr2));        // 输出false
    System.out.println(Arrays.equals(arr1, arr2)); // 输出true
    

总结

equals()方法是 Java 中用于对象内容比较的重要方法。在实际开发中,为了让对象能够按照业务逻辑进行相等性判断,我们通常需要重写该方法,并且要遵循相关规范,同时重写hashCode()方法。这样可以确保对象在集合操作(如 HashMap、HashSet)中能够正常工作。

4 和equals方法类似的相关的方法

是的,在 Java 中还有一些与equals()方法类似或相关的方法,它们在不同场景下用于比较对象或数据。以下是几个重要的相关方法:

1. hashCode()

  • 作用:返回对象的哈希码(整数),主要用于哈希表(如HashMapHashSet)。
  • equals()的关系
    • 如果两个对象通过equals()比较相等,则它们的hashCode()必须相同。
    • 如果hashCode()不同,则对象一定不相等(无需再调用equals())。
  • 示例

    java

    @Override
    public int hashCode() {return Objects.hash(name, age); // 根据属性计算哈希码
    }
    

2. compareTo()Comparable接口)

  • 作用:定义对象之间的自然排序规则,返回负数、零或正数表示当前对象 “小于”、“等于” 或 “大于” 另一个对象。
  • 适用场景:用于排序(如Collections.sort()Arrays.sort())或实现有序集合(如TreeSetTreeMap)。
  • 示例

    java

    public class Person implements Comparable<Person> {private String name;private int age;@Overridepublic int compareTo(Person other) {return Integer.compare(this.age, other.age); // 按年龄排序}
    }
    
  • equals()的关系:若compareTo()返回 0,建议equals()也返回true,但这不是强制要求(如BigDecimal)。

3. Objects.equals()

  • 作用:null 安全的equals()方法,避免NullPointerException
  • 示例

    java

    String a = null;
    String b = null;
    System.out.println(Objects.equals(a, b)); // 输出true,无需手动检查null
    

4. Arrays.equals()

  • 作用:比较数组的内容是否相等(支持多维数组,需用Arrays.deepEquals())。
  • 示例

    java

    int[] arr1 = {1, 2, 3};
    int[] arr2 = {1, 2, 3};
    System.out.println(Arrays.equals(arr1, arr2)); // 输出true
    

5. deepEquals()Objects类)

  • 作用:递归比较对象或数组的内容,适用于嵌套结构(如多维数组)。
  • 示例

    java

    Object[] arr1 = { new int[]{1, 2}, new int[]{3, 4} };
    Object[] arr2 = { new int[]{1, 2}, new int[]{3, 4} };
    System.out.println(Objects.deepEquals(arr1, arr2)); // 输出true
    

6. instanceof 关键字

  • 作用:检查对象是否是某个类或接口的实例。
  • 示例

    java

    if (obj instanceof String) {String str = (String) obj; // 安全类型转换
    }
    

7. isAssignableFrom()Class类)

  • 作用:判断一个类是否是另一个类的父类或接口。
  • 示例

    java

    List.class.isAssignableFrom(ArrayList.class); // 返回true(ArrayList实现了List)
    

8. ReferenceEquals()Object类,Java 9+)

  • 作用:等同于==,直接比较对象引用。
  • 示例

    java

    Object a = new Object();
    Object b = a;
    System.out.println(Object.referenceEquals(a, b)); // 输出true
    

总结

方法 / 关键字比较维度null 安全适用场景
equals()对象内容自定义对象相等性判断
hashCode()哈希值(配合equals哈希表(如 HashMap)
compareTo()自然排序排序和有序集合
Objects.equals()对象内容可能为 null 的对象比较
Arrays.equals()数组内容部分是一维数组比较
Objects.deepEquals()嵌套对象内容多维数组或嵌套结构比较
instanceof类型兼容性类型检查和转换
isAssignableFrom()类层次关系反射和泛型编程

根据具体场景选择合适的比较方法,可以避免NullPointerException、提高代码健壮性,并确保集合操作的正确性。

5 为java的面向编程里面的属性设置get/set方法是为什么?

它把类的内部实现和外部接口分离开来,增强了代码的安全性、可维护性和可扩展性。

在 Java 面向对象编程里,为类属性设置getset方法(也就是访问器和修改器)是很关键的封装实践,主要目的如下:

1. 访问控制

借助get/set方法,能够对属性的读写权限进行精确控制。比如,把属性设为private,仅允许通过特定方法访问,这样可以防止外部代码随意修改对象状态。

java

public class Person {private int age; // 私有属性public int getAge() { // 提供只读访问return age;}
}

2. 数据验证

set方法中,可以添加验证逻辑,保证输入数据是合法的。

java

public void setAge(int age) {if (age >= 0) { // 验证逻辑this.age = age;} else {throw new IllegalArgumentException("年龄不能为负数");}
}

3. 解耦实现细节

外部代码只需通过方法来获取或修改数据,不用关心内部的实现方式。要是后续需要对实现进行修改,比如更改数据存储格式,也不会影响外部调用。

java

// 原本直接返回属性
public Date getBirthDate() {return birthDate;
}// 改为返回计算后的年份,调用方无需修改
public int getBirthYear() {return birthDate.getYear() + 1900;
}

4. 增强安全性

可以避免直接暴露对象内部状态,降低被恶意修改的风险。

java

private List<String> secrets = new ArrayList<>();public List<String> getSecrets() {return new ArrayList<>(secrets); // 返回副本,防止外部修改原列表
}

5. 实现高级功能

在方法中能够添加额外的逻辑,像缓存、日志记录、事件触发等。

java

private int counter = 0;public void increment() {counter++;notifyObservers(); // 计数器更新时通知观察者
}

自动生成工具

现代 IDE(如 IntelliJ IDEA、Eclipse)可以自动生成get/set方法,减少了手动编写的工作量。例如:

java

public class User {private String name;private int id;// IDE自动生成的getter和setterpublic String getName() { return name; }public void setName(String name) { this.name = name; }public int getId() { return id; }public void setId(int id) { this.id = id; }
}

总结

get/set方法是实现封装的重要手段,它把类的内部实现和外部接口分离开来,增强了代码的安全性、可维护性和可扩展性。在设计类时,除非有特殊原因,否则建议将属性设为私有,并通过公共方法来控制访问。

6 equals的括号里面只可以写 Object obj 吗? 是的!

在 Java 中,重写equals方法时,参数类型必须是Object

!!!!!!!!!!这是因为equals方法是在java.lang.Object类中定义的,其签名为:

java

public boolean equals(Object obj)

当你在子类中重写这个方法时,必须保持方法签名完全一致(包括参数类型、返回类型和访问修饰符),否则就不是重写(override),而是重载(overload)一个新方法。重载的方法不会被Object.equals()的多态机制调用,导致你的比较逻辑失效。

错误示例(重载而非重写)❌的!!!!

以下代码会创建一个新的equals方法,而不是重写父类的方法:

java

// 错误!这是重载,不是重写
public boolean equals(Teacher other) { // 参数类型是 Teacher,不是 Objectreturn this.no.equals(other.no);
}

这种写法会导致以下问题:

  1. 当你调用teacher1.equals(teacher2)时,如果teacher2被声明为Object类型,实际执行的是Object.equals(),而非你定义的方法。
  2. 违反了equals方法的对称性原则(a.equals(b)b.equals(a)可能结果不同)。

正确示例(重写)✔的哦~~~~~~

java

@Override
public boolean equals(Object obj) {if (this == obj) return true;if (obj == null || !(obj instanceof Teacher)) return false;Teacher other = (Teacher) obj;return this.no.equals(other.no);
}

为什么必须是Object

Java 的多态机制依赖于方法签名的一致性。当你调用obj.equals(other)时:

  1. 编译时:编译器只知道objObject类型,因此会查找Object.equals(Object)方法。
  2. 运行时:根据obj的实际类型(如Teacher),动态调用其重写的equals(Object)方法。

如果参数类型不是Object,编译器会认为这是一个全新的方法,无法通过多态调用。

总结

  • 重写equals时,参数必须是Object类型
  • 如果使用其他参数类型(如Teacher),会导致方法重载,而非重写,从而使equals失效。
  • 重写时建议添加@Override注解,让编译器帮你检查方法签名是否正确。
http://www.xdnf.cn/news/6857.html

相关文章:

  • windows编程中加载DLL的两种典型方式的比较
  • 找客户的app
  • 人脸表情识别检测数据集VOC+YOLO格式9400张8类别
  • Quartus qsf 文件 常用约束指令分析
  • 【C++】STL简介
  • 保存主表信息以及关联信息
  • 青少年ctf平台应急响应-应急响应1
  • 测试:TestCafe - 判断按钮是否活性化
  • ROS资料推荐学习
  • GCC 版本与C++ 标准对应关系
  • JWT令牌
  • 记一次从windows连接远程Linux系统来控制设备采集数据方法
  • 武器装备论证全流程分析
  • GDB 高级调试技术深度解析
  • 自定义类型-结构体传参
  • 京东方10.1寸工业液晶屏GV101WXM-N80
  • 【在aosp中,那些情况下可以拉起蓝牙服务进程】
  • 道路运输企业管理人员考试真题练习
  • Shotcut:免费开源的视频编辑利器
  • [特殊字符] Maven配置阿里云镜像终极指南(2024最新版)
  • DevExpressWinForms-GridControl-无限滚动
  • “数据类型与OOP核心”的一些问题
  • 团队模式总结
  • python第二十七天
  • 吉客云数据集成到金蝶云星空的最佳实践
  • ai agent(智能体)开发 python高级应用4:什么是代理,如何设置squid代理服务器,让crawl4ai 0.6.3 用上代理,获取到数据平权
  • MySQL中表的增删改查(CRUD)
  • 【Win32 API】 lstrcpyA()
  • Python3.12之解决:externally-managed-environment问题(二十九)
  • 薄膜压力传感器主要应用场景