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

技术周总结10.28~11.03 周日

文章目录

  • 一、10.30 周三
    • 1.1)问题01:一个Java对象的属性被定义变量后,这个变量再被修改为别的值,则原java对象的这个属性值也会变化吗?
    • 1.2)问题02:Java函数的入参是一个 引用对象,比如是一个布尔对象Boolean,在函数内部修改这个变量的值,会导致 函数外的这个引用对象的布尔对象 Boolean发生变化吗?
    • 1.3)问题03:Java中哪些是可变的引用类型,哪些是不可变的引用类型?
    • 1.4) 问题04: 不可变引用类型的例子
    • 1.5)问题05: Java中引用变量赋值和引用变量修改的区别

一、10.30 周三

1.1)问题01:一个Java对象的属性被定义变量后,这个变量再被修改为别的值,则原java对象的这个属性值也会变化吗?

在Java中,对象的属性(成员变量)的行为取决于属性的数据类型:

  • 基本数据类型(如 int, double, float, boolean 等)是按值传递的。当你将一个对象的基本类型属性赋值给另一个变量时,实际上是将值的副本赋给了那个变量。修改这个新变量不会影响原对象的属性值。

  • 引用数据类型(如数组、类对象等)是按引用传递的。当你将一个对象的引用类型属性赋值给另一个变量时,实际上是将属性的引用(即内存地址)赋给了那个变量。如果通过这个新变量修改了对象内的数据,那么原对象的相应属性也会被修改,因为它们指向的是同一块内存地址。

下面是一个简单的例子来说明这一点:

public class Example {int number; // 基本数据类型Integer[] array; // 引用数据类型public static void main(String[] args) {Example obj = new Example();obj.number = 10;obj.array = new Integer[1];obj.array[0] = 100;// 基本数据类型的测试int copyNumber = obj.number;copyNumber = 20; // 修改副本// 引用数据类型的测试Integer[] copyArray = obj.array;copyArray[0] = 200; // 修改引用指向的对象System.out.println(obj.number); // 输出 10,因为基本数据类型的值没有改变System.out.println(obj.array[0]); // 输出 200,因为引用类型的对象已经被修改了}
}

在这个例子中,修改了 copyNumber 并不会改变 obj.number,因为它是基本数据类型。但是修改 copyArray[0] 会改变 obj.array[0],因为它们都指向同一个数组对象。

1.2)问题02:Java函数的入参是一个 引用对象,比如是一个布尔对象Boolean,在函数内部修改这个变量的值,会导致 函数外的这个引用对象的布尔对象 Boolean发生变化吗?

在Java中,Boolean 类型是一个不可变的引用类型。这意味着一旦一个 Boolean 对象被创建,它的值就不能被改变。如果你尝试在一个方法内部修改一个 Boolean 对象的值,实际上你会创建一个新的 Boolean 对象,而原始的 Boolean 对象不会被修改。

要理解这一点,关键是要记住:方法参数是按值传递的。当一个对象实例传递给一个方法时,传递的是对象引用的副本,而不是对象本身。对于不可变对象,这意味着你不能改变原始对象,但是你可以改变持有对象引用副本的变量,使其指向一个新的对象。

下面是一个例子来说明这个概念:

public class TestBoolean {public static void main(String[] args) {Boolean originalValue = Boolean.FALSE;System.out.println("Before method call: " + originalValue); // 输出 falsechangeValue(originalValue);System.out.println("After method call: " + originalValue); // 依然输出 false}public static void changeValue(Boolean value) {value = Boolean.TRUE;}
}

在这个例子中,尽管在changeValue方法内部尝试将value设置为Boolean.TRUEoriginalValue的值并没有改变。这是因为valueoriginalValue的一个引用副本,修改value引用的变量让它指向了一个新的Boolean对象,而originalValue仍然指向原来的Boolean.FALSE对象。

如果你需要在方法内部修改一个引用类型的对象,并希望这些修改反映到方法外部,你需要确保操作的是可变对象。对于布尔值,通常的做法是使用一个包含布尔字段的可变类,比如下面BooleanWrapper类的例子。

public class BooleanWrapper {public boolean value;public BooleanWrapper(boolean value) {this.value = value;}
}public class Test {public static void main(String[] args) {BooleanWrapper originalValue = new BooleanWrapper(false);System.out.println("Before method call: " + originalValue.value); // 输出 falsechangeValue(originalValue);System.out.println("After method call: " + originalValue.value); // 输出 true}public static void changeValue(BooleanWrapper valueWrapper) {valueWrapper.value = true;}
}

1.3)问题03:Java中哪些是可变的引用类型,哪些是不可变的引用类型?

在Java中,对象的可变性是由其类的设计决定的。以下是一些常见的不可变和可变引用类型的例子:

不可变的引用类型

  1. 基本数据类型的包装类:所有的基本数据类型的包装类都是不可变的。这包括:

    • Integer
    • Long
    • Byte
    • Short
    • Float
    • Double
    • Character
    • Boolean
  2. StringString 类在Java中是不可变的。一旦创建了一个String对象,就不能更改它的内容。

  3. BigInteger 和 BigDecimal:这些类用于表示大的整数和十进制数,它们也是不可变的。

  4. 其他不可变类:许多来自Java标准库的类是设计为不可变的,例如 Path 类、Locale 类等。

可变的引用类型

  1. 集合类:大部分的Java集合类都是可变的,例如:

    • ArrayList
    • LinkedList
    • HashSet
    • TreeSet
    • HashMap
    • TreeMap
    • 等等
  2. StringBuilder 和 StringBuffer:这些类是String的可变对应类,主要用于在需要频繁修改字符串内容时使用。

  3. Java Beans 和 POJOs:通常自定义的类,除非特别设计为不可变,否则它们是可变的。这包括Java Beans和普通的Java对象(POJOs)。

  4. 日期和时间类:在Java 8之前,日期和时间的API(如java.util.Datejava.util.Calendar)是可变的。然而,在Java 8及以后的版本中,引入了新的日期和时间API(如LocalDateLocalTimeLocalDateTime),它们是不可变的。

  5. 数组:所有数组类型(无论是基本数据类型还是对象数组)都是可变的。你可以更改数组中的元素,但不能更改数组的大小。

理解一个类是否可变通常需要查看其API文档。如果一个类没有提供修改其状态的方法,或者文档明确说明它是不可变的,那么它就是不可变的。相反,如果一个类提供了可以改变其状态的方法(比如setter方法),那么它就是可变的。设计不可变类的一个关键特点是它们通常不提供修改对象状态的方法,并且它们的所有字段都是final的。

1.4) 问题04: 不可变引用类型的例子

下面代码的运行情况怎样?

public class BooleanWrapper {public Boolean value;public BooleanWrapper(boolean value) {this.value = value;}
}public class Test {public static void main(String[] args) {BooleanWrapper originalValue = new BooleanWrapper(false);Boolean value = originalValue.value;value = true;System.out.println("After method call: " + originalValue.value); }}

在这个代码示例中,BooleanWrapper 类的 value 字段是一个 Boolean 对象(引用类型),而不是 boolean 基本数据类型。在 main 方法中,创建了一个 BooleanWrapper 实例 originalValue,并将其 value 字段初始化为包装了基本数据类型 falseBoolean 对象。

然后,声明了一个 Boolean 类型的变量 value 并将 originalValue.value 的引用赋给了它。接着,value 被设置为 true。这里的关键点是,value 是一个 Boolean 类型的变量,它现在指向一个新的 Boolean 对象 true,但这个操作并不影响 originalValue 对象的 value 字段,因为 Boolean 是不可变的,你不能通过 value 变量改变 originalValue.value 所引用的 Boolean 对象的内部状态。

由于 originalValue.valuevalue 是两个独立的引用,它们最初指向同一个 Boolean 对象(包装了 false),但在 value = true; 这行代码之后,value 变量引用了一个新的 Boolean 对象(包装了 true),而 originalValue.value 仍然引用原来的 Boolean 对象(包装了 false)。

因此,当我们在 main 方法的最后打印出 originalValue.value 的值时,它仍然是 false,因为 originalValue.value 引用的 Boolean 对象并没有被改变。

所以,输出结果将会是:

After method call: false

1.5)问题05: Java中引用变量赋值和引用变量修改的区别

public class BooleanWrapper {public Boolean value;public List<Integer> list;public BooleanWrapper(boolean value, List<Integer> list) {this.value = value;this.list = list;}
}public class Test {public static void main(String[] args) {BooleanWrapper originalValue = new BooleanWrapper(false, new ArrayList(Arrays.asList(111)));List<Integer> list = originalValue.list;list.add(222); // 此时,会影响 originalValue.list 为[111,222]list = Arrays.asList(333); // 此时,不会影响 originalValue.list,其还是 为[111,222] ,只是 list为 [333]了System.out.println("After method call: " + originalValue.list); }}

http://www.mrgr.cn/news/64202.html

相关文章:

  • 2022高等代数下【南昌大学】
  • 索引的数据结构和存储引擎是有关系吗
  • 使用python读取数据建立pptx (python-pptx图文调整案例)
  • 期权懂|场内个股期权开户流程有哪些?
  • yagmail邮件发送库:如何用Python实现自动化邮件营销?
  • java垃圾回收机制介绍
  • 动态规划-回文串系列——1312.让字符串变成回文串的最小插入次数
  • 祖鲁法则精要
  • 实习冲刺Day11
  • 如何利用8款工具辅助建立需求管理体系
  • CAN协议
  • 【P2-1】ESP8266 WIFI模块STA、AP、STA+AP、TCP/UDP透传工作模式介绍与AT指令介绍
  • Aicbo:解锁AI创意新纪元,一键生成视频、绘画与文字!
  • gesp的python二级题目
  • python 调用shell 脚本
  • 【机器学习】机器学习算法-线性回归算法
  • springboot河南旅游推荐系统-计算机毕业设计源码33358
  • DNS域名解析服务器--RHCE
  • Git本地分支更新推送到远程主分支上
  • 1231243545347ikih
  • 江协科技STM32学习- P33 实验-软件I2C读写MPU6050
  • 裸金属服务器和普通服务器的不同之处
  • 决策树算法
  • Java实战项目-基于 SpringBoot+Vue 的医院管理系统
  • Qt的程序如何打包详细教学
  • 无桥图腾柱PFC -- 基于平均电流的双闭环仿真