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

第02周 预习:Java基础语法2、面向对象入门 - hohohoho--

第02周 预习:Java基础语法2、面向对象入门

项目名称 内容
课程名称 java
班级 网安2413
学生姓名 王璐
学号 202421336068

预习

1.1 学习目标

  1. 掌握引用类型及常见类:数组、数组列表(ArrayList)、方法及引用类型作为方法参数
  2. 掌握类、对象、方法、属性相关基本概念,对象的初始化。
  3. 能使用IDE快速创建对象。

1.2

1.方法相关问题

public class Main {static void changeStr(String x) {x = "xyz";}static void changeArr(String[] strs) {for (int i = 0; i < strs.length; i++) {strs[i] = strs[i]+""+i;}}public static void main(String[] args) {    String x = "abc";changeStr(x);System.out.println(x);changeArr(args);System.out.println(Arrays.toString(args));}
}

对于如上代码:
1.1 changeStr与changeArr的功能各是什么?
1.2 main方法的x有没有被改变?为什么?
1.3 main方法的args数组的内容有没有被改变?为什么?
1.4 args数组中的值是从哪里来的?要怎么才能给他赋值。

1.1 changeStr功能:将传入的字符串参数修改为"xyz",但实际不会影响原变量
changeArr功能:遍历传入的字符串数组,将数组中每个元素修改为 "原始元素值+索引值"

1.2 main方法的x有没有被改变?为什么?
没有被改变,因为Java 中字符串是不可变对象,且方法参数传递的是 "值传递"。

1.3 main方法的args数组的内容有没有被改变?为什么?
被改变了,因为数组是引用类型方法参数传递的是数组的引用(地址)的副本

  • main方法中的args和changeArr方法的参数strs指向同一个数组对象。
  • 方法内部通过strs[i] = ...修改的是数组内部元素(操作的是同一个数组对象),因此main方法中的args数组内容会同步被改变。

1.4 args数组中的值是从哪里来的?要怎么才能给他赋值。

  • args数组是main方法的参数,它的值来源于程序运行时传递的命令行参数。
  • 1.给args数组赋值的方式就是在运行程序时通过命令行传递参数:
    首先使用javac Main.java编译Java文件生成 class 文件
    然后使用java Main 参数1 参数2 参数3...的形式运行程序,其中空格分隔的每个部分都会成为args数组的一个元素
  • 2.在IntelliJ IDEA中运行程序,可以通过配置运行参数的方式为args数组赋值

2.数组相关问题
对于如下程序

int[] arr = new int[3];
arr[0] = 1; arr[1] = 1;
int[] arrX = arr;
arr[0] = 2;
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arrX));

2.1这段程序输出结果是什么?为什么?

输出的结果都是[2, 1, 0]

  1. 因为数组属于引用类型。当执行int[] arrX = arr;时,并没有创建新的数组对象,而是让arrX和arr指向同一块内存地址(即引用同一个数组对象)。
  2. 因此,当通过arr[0] = 2修改数组元素时,arr和arrX引用的是同一个数组,所以两者的输出结果完全相同
  3. 数组初始化时未赋值的元素(如arr[2])会使用默认值,int类型的默认值为0。
String[] strArr = {"aa","bb","cc"};
strArr[1] = "xx";
System.out.println(Arrays.toString(strArr));

2.2字符串是不可变类,为什么可以对strArr[1]赋值"xx"。

字符串的 "不可变" 是指字符串对象本身的内容不可修改(如"bb"这个字符串不能被改变)。

但在strArr[1] = "xx"中,我们并不是修改原有字符串"bb"的内容,而是:

  1. 创建了一个新的字符串对象"xx";
  2. 将数组strArr的第 1 个元素(原本指向"bb")重新指向了新的字符串对象"xx"。

3.使用int[5][]定义一个二维数组,其第二维到底有多长?尝试补全代码,然后使用foreach获其他循环方法遍历这个二维数组?

第二维的长度是不确定的

import java.util.Arrays;  
public class Main {  public static void main(String[] args) { int[][] arr = new int[5][];  arr[0] = new int[2];  arr[1] = new int[3];  arr[2] = new int[1];arr[3] = new int[4];arr[4] = null;arr[0][0] = 1;arr[0][1] = 2;  arr[1][0] = 3;arr[1][1] = 4;arr[1][2] = 5;  arr[2][0] = 6;  arr[3][0] = 7;arr[3][1] = 8;arr[3][2] = 9;arr[3][3] = 10;  System.out.println("二维数组各行的长度与内容:");  for (int i = 0; i < arr.length; i++) {  System.out.println("第" + i + "行(长度:" +  (arr[i] == null ? "null" : arr[i].length) +  "):" +  Arrays.toString(arr[i]));  }  //使用foreach循环遍历  System.out.println("\n使用foreach遍历所有元素:");  for (int[] row : arr) { if (row != null) {for (int num : row) {  System.out.print(num + " ");  }  }   else {  System.out.print("(null) ");  }  }  // 使用for循环遍历  System.out.println("\n\n使用for循环遍历所有元素:");  for (int i = 0; i < arr.length; i++) {  if (arr[i] != null) {  for (int j = 0; j < arr[i].length; j++) {  System.out.print(arr[i][j] + " ");  }  }   else {  System.out.print("(null) ");  }  }  }  
}

4.类与对象的区别是什么? Math类有对象吗?String类有什么属性是private的,有什么方法是public的,为什么这样设计(尝试举两例说明)?

区别维度 类(Class) 对象(Object)
定义 抽象的模板,描述一类事物的共同属性和行为 具体的实例,是类的具象化产物
存在形式 逻辑概念,不占用内存 物理实体,占用内存空间
关系 类是对象的抽象,对象是类的实例化结果 一个类可以创建多个对象,对象依赖类存在

Math 类没有对象.
Math 类是 Java 中的工具类,其构造方法被声明为private,且所有方法和属性都是static(静态)的。所以无法通过new Math()创建对象;只能通过Math.方法名()直接调用其功能(如Math.random()Math.sqrt())。

String类

private public
private final char value[],存储字符串的字符数组,final修饰表示一旦赋值不可修改(保证字符串不可变)。 public int length(),返回字符串长度(通过value.length实现)。
private int hash,缓存字符串的哈希值,避免每次调用hashCode()时重新计算,提高效率。 public String substring(int beginIndex),截取子字符串(返回新的 String 对象,不修改原字符串)。

原因:

  1. 安全性
    私有属性value[]防止外部直接修改字符数组。如果允许外部修改,可能导致字符串在多线程环境中出现不可预期的行为,或破坏依赖字符串内容的逻辑(如哈希表中的键)。
  2. 封装性与可控性
    通过公共方法(如substring())提供修改逻辑,但返回新对象而非修改原对象,保证了字符串的不可变性。这种设计使 String 可以安全地作为 HashMap 的键,且多线程环境下无需额外同步。
  3. 性能优化
    私有属性hash缓存哈希值,使hashCode()调用从 O (n) 优化为 O (1),提升哈希表等场景的效率。公共方法length()直接返回value.length,既便捷又不暴露内部存储细节。

5.将类的属性设置为public可以方便其他类访问,但为什么Java中普遍使用setter/getter模式对对象的属性进行访问呢?这与封装性又有什么关系?

  1. 控制访问权限,实现 "读写分离"
  2. 添加数据校验,保证属性合法性

封装性 : 通过 private 属性隐藏内部数据,仅通过公共方法暴露访问接口,实现 "隐藏细节、暴露必要接口"。

6.对象的属性可在什么时候进行初始化?都有哪些进行初始化的办法?

初始化时机:

  • 静态属性:仅在类第一次被加载时,通过静态初始化块或声明时初始化,且只执行一次。
  • 非静态属性:在对象创建时初始化,执行顺序为:声明时初始化 → 初始化块 → 构造方法。
  1. 声明时直接初始化
  2. 构造方法中初始化
  3. 初始化块(代码块)初始化
  4. 静态初始化块(针对静态属性)

7.进阶(可选):尝试使用作用域来说明封装性。

封装性的核心是通过控制作用域来隐藏类的内部实现细节,只暴露必要的接口供外部访问。Java 中的作用域修饰符(privatedefaultprotectedpublic)直接决定了类成员(属性和方法)的可访问范围,是实现封装的技术基础。

作用域修饰符从 "最严格" 到 "最宽松" 的顺序为:
privatedefault(默认,无修饰符) → protectedpublic
它们的访问范围限制直接体现了封装的 "隐藏" 与 "暴露" 原则:

  1. private(私有):仅在当前类内部可访问
  • 这是封装性最严格的体现,完全隐藏类的内部细节(如属性的存储、内部计算逻辑)。
  • 例:String类的private char value[]属性,外部无法直接修改字符数组,只能通过public方法(如charAt())间接访问,保证了字符串的不可变性。
  1. default(默认):仅在同一包内可访问
  • 适用于包内组件的协作,对外隐藏(不同包的类无法访问),实现包级别的封装。
  • 例:工具类中辅助方法标记为默认,仅包内其他工具类可调用,避免外部误用。
  1. protected(受保护):同一包内或子类可访问
  • 在隐藏的基础上,为继承关系保留必要的扩展接口,是封装与继承的平衡。
  • 例:父类的protected void init()方法,允许子类重写初始化逻辑,但禁止无关类调用。
  1. public(公共):任何地方可访问
  • 是类对外暴露的 "接口",仅开放必要的功能(如getter方法、业务方法),体现封装的 "最小权限原则"。
  • 例:ArrayListpublic int size()方法,外部只需知道集合大小,无需关心内部数组的存储细节。

总结

封装性通过作用域修饰符划定了类成员的访问边界:

  • private隐藏核心实现(如属性、内部工具方法),确保类对自身状态的绝对控制;
  • public(或protected)暴露必要接口,允许外部以可控方式使用类的功能。
http://www.wxhsa.cn/company.asp?id=1905

相关文章:

  • 第六届机器学习与计算机应用国际学术会议(ICMLCA 2025)
  • 设计模式-享源模式 - MaC
  • # 数论知识讲解与C++代码:唯一分解定理、辗转相除法、埃氏筛与线性筛(含质因数分解示例)
  • 第九届交通工程与运输系统国际学术会议(ICTETS 2025)
  • 小红书开源 FireRedTTS-2;全栈开源应用+嵌入式+电路设计:BUDDIE AI 语音交互方案丨日报
  • 设计模式-外观模式 - MaC
  • 深度解析 ADC 偶联技术:从随机偶联到定点偶联,如何平衡抗肿瘤 ADC 的活性、稳定性与均一性?
  • 豆包P图大更新,网友们已经玩嗨了。
  • 【初赛】无向图度数性质 - Slayer
  • $p\oplus q=r$
  • 2025年金融行业API安全最佳实践:构建纵深防御体系
  • Jack-of-All-Trades
  • Matlab的交通标志定位实现
  • 怎样在 Salesforce Flow 中获取当前 Salesforce 组织的 URL
  • reLeetCode 热题 100-3 最长连续序列扩展 排序算法 - MKT
  • vuejs3.0 从入门到精通【左扬精讲】—— 从原生到原子化:一文梳理现代 CSS 技术体系(2025 版)
  • java中JSON字符串处理的踩坑
  • 11111
  • 阿里云微服务引擎 MSE 及 API 网关 2025 年 8 月产品动态
  • TIA Portal中S7-1500F CPU与ET200SP安全模块的配置例程(转载)
  • 获取第一个运行的Word应用程序实例
  • S7-1500 TRACE功能组态 (转载)
  • 如何在Proxmox VE中使用fdisk命令行扩展LVM存储池 - 若
  • 垃圾AV覆盖defender
  • SAP-PO:怎么控制传输的内容在单数据情况下是数组格式还是单对象格式
  • 开源新基建:数字中国创新发展的底层密码与生态实践
  • 员工离职停用Salesforce帐号?这11个“坑”千万别踩!
  • Linux的运行模式
  • Spring Boot + MybatisX,效率翻倍!
  • 条码控件Aspose.BarCode教程:使用 Java 自动生成 DotCode 条形码