news 2026/9/14 22:46:31

【Java SE】类和对象(二)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Java SE】类和对象(二)

本节目标

  1. 理解包(package)的作用,掌握导入类、自定义包、常用系统包
  2. 理解面向对象三大特性之封装,掌握四种访问权限修饰符、get/set 方法
  3. 深度掌握static关键字:静态成员变量、静态成员方法,分清实例与静态的区别
  4. 掌握四种代码块:普通代码块、实例(构造)代码块、静态代码块,熟悉执行顺序

1. 包 package

1.1 什么是包

包是 Java 组织管理类的一种机制,类似电脑文件夹目录。 作用:

  1. 解决类名冲突:不同包下面可以有相同名字的类,不会冲突。
  2. 分类管理大量的类,提高代码可读性,项目结构清晰。

类比电脑磁盘文件夹:把 C 语言作业、Java 作业、数据结构作业分不同文件夹存放。Java 使用包对类、接口进行分层组织。

1.2 使用包里面已有的类(import 导入)

Java JDK 自带大量已经写好的类,例如java.util.Date时间类。

方式 1:写完整全限定类名(不推荐,写起来冗长)
public class Test { public static void main(String[] args) { // 完整包名+类名 java.util.Date date = new java.util.Date(); System.out.println(date.getTime()); } }
方式 2:import 包名.类名;显式导入指定类(推荐)
import java.util.Date; public class Test { public static void main(String[] args) { Date date = new Date(); System.out.println(date.getTime()); } }
方式 3:通配符导入import java.util.*;

*代表导入该包下所有类

import java.util.*; public class Test { public static void main(String[] args) { Date date = new Date(); System.out.println(date.getTime()); } }

⚠️通配符缺点:如果两个不同包存在同名类,会出现类名歧义,编译报错。

冲突案例:java.util.Datejava.sql.Date两个包都有 Date 类。

import java.util.*; import java.sql.*; public class Test { public static void main(String[] args) { // 编译报错!分不清是util的Date还是sql的Date // Date date = new Date(); // 出现冲突时,写完整全限定类名 java.util.Date date = new java.util.Date(); System.out.println(date.getTime()); } }
静态导入import static

导入类里面静态的字段、静态方法,调用的时候不需要写类名。

import static java.lang.Math.*; public class Test { public static void main(String[] args) { double x = 30; double y = 40; // 原本写法 Math.sqrt(Math.pow(x,2)+Math.pow(y,2)); double result = sqrt(pow(x, 2) + pow(y, 2)); System.out.println(result); } }

1.3 自定义包

1.3.1 自定义包语法规则
  1. .java源文件最顶部package 包名;,必须放在所有 import 之前。
  2. 包名习惯使用公司域名颠倒,例如com.bit.demo1;全部小写,不要大写。
  3. 包名和磁盘文件目录严格对应:com.bit.demo1对应文件夹路径com/bit/demo1/
  4. 如果文件没有写package,该类属于默认无名包,不适合正式项目。
package com.bit.demo1; public class Test { public static void main(String[] args) { } }
1.3.2 IDEA 创建包操作步骤

1.在src目录右键 →NewPackage

2.输入包名:com.bit.demo1,IDEA 会自动创建多级文件夹。

3.在包上面右键 →NewClass,输入类名。

4.生成的代码第一行自动生成package com.bit.demo1;

1.3.3 Java 常用系统包

表格

包名用途
java.lang核心基础类:String、Object、包装类;自动导入,不需要写 import
java.lang.reflect反射相关 API
java.net网络编程 Socket
java.sql数据库 JDBC 编程
java.util工具包!集合 ArrayList、Scanner、日期工具,开发高频
java.io文件 IO 输入输出流

1.4 包访问权限(default 默认权限)

类、成员变量、方法不写任何访问修饰符,就是包访问权限(default)。 ✅同一个包里面的类可以访问;不同包完全不能访问

示例:com.bit.demo1包下 Computer 类

package com.bit.demo1; public class Computer { private String cpu; private String memory; public String screen; // default包访问权限,不加修饰符 String brand; public Computer(String brand, String cpu, String memory, String screen) { this.brand = brand; this.cpu = cpu; this.memory = memory; this.screen = screen; } public void Boot(){ System.out.println("开机~~~"); } }

com.bit.demo2不同包访问 Computer

package com.bit.demo2; import com.bit.demo1.Computer; public class TestComputer { public static void main(String[] args) { Computer p = new Computer("HW", "i7", "8G", "13*14"); System.out.println(p.screen); // public可以访问 // System.out.println(p.cpu); // ❌private,本类之外不能访问 // System.out.println(p.brand); // ❌default包访问,跨包不能访问 } }

2. 封装

面向对象三大特性:封装、继承、多态,本章节重点学习封装。

2.1 封装概念

封装:把数据(成员变量)和操作数据的方法包装到类当中;隐藏内部实现细节,只对外暴露安全的公共接口

生活类比笔记本电脑: 电脑主板、CPU 内部复杂电路全部被外壳封装隐藏;用户不需要懂电路,只使用开机、键盘、USB 这些对外接口。内部零件改动,不影响用户使用。

代码实现封装:

  1. 成员变量使用private私有修饰,类外部不能直接访问。
  2. 对外提供getXxx()获取值、setXxx()设置值公共方法,作为访问数据的唯一接口。

基础版本(未封装,外部可以直接随意修改成员)

class Student{ private String name; private int age; public void eat() { System.out.println(this.name + " 正在吃饭!"); } public void show() { System.out.println("name: "+name+" 年龄:"+age); } }

提供 get/set 对外访问接口:

class Student{ //私有,外部类不能直接访问 private String name; private int age; //get 获取name public String getName() { return name; } //set 设置name public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { // 在set里面可以增加逻辑校验,比如年龄不能负数 if(age >= 0 && age <= 150){ this.age = age; } } public void eat() { System.out.println(this.name + " 正在吃饭!"); } public void show() { System.out.println("name: "+name+" 年龄:"+age); } } public class Test { public static void main(String[] args) { Student stu= new Student(); stu.setAge(10); System.out.println(stu.getAge()); } }

✨封装三大好处

  1. 降低耦合:类内部实现修改,只要对外公共接口不变,外部调用代码不需要改动。
  2. 简化使用:隐藏复杂内部细节,使用者只调用公开接口,不用关心内部实现。
  3. 提高安全性:可以在 set 方法做参数校验,阻止外部随意篡改非法数据。

2.2 四种访问权限修饰符

表格

修饰符本类内部同一个包子类 (不同包)其他包普通类
private私有
default(不写修饰符,包访问)
protected保护
public公开

说明:

  1. private:只允许当前类内部访问。
  2. default:不加任何修饰,包访问权限,仅限同一个包
  3. protected保护:后续继承章节详细讲解。
  4. public:任何地方都可以访问。

开发编码习惯:成员变量尽量private;对外提供 get/set 公共接口。

3. static 关键字

static 可以修饰成员变量、成员方法

区分两个概念:

  • 实例成员:没有 static 修饰,属于对象,每个对象各自拥有一份。必须通过对象引用访问。
  • static 静态成员(类成员):属于类,所有对象共享一份,存放在方法区。

3.1 static 修饰成员变量(静态成员变量)

场景:多个学生,都在同一个教室上课。教室不属于某一个学生,全部学生共享同一个教室信息

如果写普通实例变量:每个 new 出来 Student 对象,都会单独存一份 classRoom,内存浪费,数据容易不一致。

class Student{ private String name; private int age; public String classRoom; //实例变量,每个对象单独一份 }

使用 static 定义静态成员变量:

class Student{ private String name; private int age; //静态成员变量:属于类,所有对象共享 public static String classRoom = "1‑101"; }
静态成员变量核心特性
  1. 不属于某一个对象,属于类,所有对象共享同一份数据,不在对象堆内存中存储。
  2. 存储位置:方法区
  3. 生命周期:类加载的时候创建;类卸载销毁,生命周期比对象长。
  4. 推荐使用类名.静态变量访问;也可以对象引用访问(不推荐)。
public class Test { public static void main(String[] args) { // ✅推荐:类名直接访问静态成员 System.out.println(Student.classRoom); Student stu1 = new Student(); Student stu2 = new Student(); Student stu3 = new Student(); // 不推荐,虽然语法允许,容易误导以为属于对象 System.out.println(stu1.classRoom); System.out.println(stu2.classRoom); System.out.println(stu3.classRoom); // 修改静态变量,全部对象看到修改后的值 Student.classRoom = "2‑202"; } }

3.2 static 修饰成员方法(静态方法,类方法)

public class Student{ private static String classRoom = "Bit306"; //静态成员方法 public static String getClassRoom(){ return classRoom; } } public class TestStudent { public static void main(String[] args) { //推荐类名调用 System.out.println(Student.getClassRoom()); } }
静态方法重要特性(面试高频)
  1. 属于类,不是对象的方法。推荐类名.方法()调用。
  2. 静态方法里面不能直接访问实例成员变量(非 static 成员)
  3. 静态方法里面不能使用this关键字,this 代表当前对象,静态方法没有对象。
  4. 静态方法不能直接调用普通实例成员方法,实例方法依赖 this 对象。

错误示例:

class Student{ private int age; private static String room; public static void func(){ // System.out.println(this.age); //编译报错,静态没有this // age = 10; //编译报错,不能访问实例成员 // eat(); //编译报错,不能直接调用实例方法 } public void eat(){ } }

反过来:普通实例成员方法,可以访问静态成员变量、调用静态方法。实例方法有 this,静态属于类全局存在。

3.3 静态成员变量两种初始化方式

  1. 就地初始化:定义的时候直接赋值
private static String classRoom = "1‑101";
  1. 静态代码块初始化,适合复杂逻辑初始化。

注意:静态成员不要放到构造方法初始化,构造方法是 new 对象的时候执行,静态属于类加载阶段。

4. 代码块

使用{ }包裹的一段代码叫代码块,一共 4 种:

  1. 普通代码块
  2. 实例代码块(构造代码块)
  3. 静态代码块
  4. 同步代码块(多线程后续讲解)

4.1 普通代码块

写在方法内部{},限定局部变量作用域。

public class Main{ public static void main(String[] args) { { int x = 10 ; System.out.println("x1 = " +x); } // x 出了大括号,作用域结束,不能再使用 int x = 100 ; System.out.println("x2 = " +x); } }

输出:

x1 = 10 x2 = 100

4.2 实例代码块(构造代码块)

写在类里面,方法外面,不加任何修饰符。

作用:用于初始化实例成员变量。 执行时机:每次 new 对象实例化的时候执行,在构造方法之前执行

public class Student{ private String name; private int age; private String gender; //实例代码块 { this.name = "bit"; this.age = 12; this.gender = "man"; System.out.println("I am instance init()!"); } public Student() { System.out.println("I am Student init()!"); } public void show(){ System.out.println("name: "+name+" age: "+age+" sex: "+gender); } } public class Main { public static void main(String[] args) { Student stu = new Student(); stu.show(); } }

输出:

I am instance init()! I am Student init()! name: bit age: 12 sex: man

每 new 一个对象,实例代码块执行一次;多个对象就执行多次。执行顺序:实例代码块 → 构造方法

4.3 静态代码块

使用static { }修饰,写在类中方法外。

用途:专门初始化静态成员变量。 ⚠️执行时机:类加载的时候执行,无论 new 多少对象,静态代码块只会执行唯一一次!

public class Student{ private String name; private int age; private static String classRoom; //实例代码块 { this.name = "bit"; this.age = 12; System.out.println("I am instance init()!"); } //静态代码块 static { classRoom = "bit306"; System.out.println("I am static init()!"); } public Student(){ System.out.println("I am Student init()!"); } } public static void main(String[] args) { Student s1 = new Student(); Student s2 = new Student(); }

输出:

I am static init()! I am instance init()! I am Student init()! I am instance init()! I am Student init()!

执行顺序总结:

  1. 类加载,静态代码块最先执行,只跑一次
  2. new 对象:实例代码块执行 → 构造方法执行。

如果类写多个静态代码块,编译器会按照书写先后顺序合并执行。

5. 课后习题

选择题 1

以下说法哪个是正确的? A. 在静态的成员方法当中,可以使用非静态成员变量 B. 在静态的成员方法当中,可以使用 this 关键字 C. 在非静态的成员方法当中,可以使用静态成员变量 D. 静态的成员方法和静态的成员变量,属于对象也就是在每个对象中都包含

✅答案:C解析: A:静态方法不能访问实例成员。 B:静态没有 this。 C:实例方法可以访问静态成员,正确。 D:static 属于类,不属于对象。

选择题 2

关于 Java 中的封装,以下哪个陈述是正确的? A. 封装要求所有类成员都必须被声明为 private。 B. 使用 public getter 和 setter 方法可以直接访问私有变量,因此破坏了封装。 C. 封装允许在不影响使用类的代码的情况下修改类的内部实现。 D. 封装主要用于增加程序的运行速度。

✅答案:C解析 A:不是全部成员必须 private。 B:get/set 正是封装对外提供的接口,不会破坏封装。 C:公共接口不变,内部实现可以修改,正确。 D:封装和运行速度无关,提升维护性安全性。

📝本篇核心考点总结

  1. 包 package:管理类,防止类名冲突;import导入类;import static静态导入;java.util高频工具包。同名类冲突要写完整全限定名。
  2. 封装:隐藏内部细节,成员 private,对外提供 get/set 公共接口;提高安全、降低耦合。
  3. 访问权限:private < default包访问 < protected < public
  4. static 静态
    • 静态成员属于,所有对象共享,存放在方法区。推荐类名.静态访问。
    • 静态方法不能使用 this,不能直接访问实例成员变量 / 实例方法;实例方法可以访问静态。
  5. 代码块
    • 普通代码块:写在方法内,限制局部变量作用域。
    • 实例代码块(构造代码块):new 对象执行,先于构造方法,每 new 一次执行一次,初始化实例成员。
    • 静态代码块:类加载执行,只执行 1 次,初始化静态成员。
    • 执行顺序:静态代码块 (仅一次) → new 对象:实例代码块 → 构造方法。

面试简答

Q:静态代码块和实例代码块执行顺序?

A:类加载执行静态代码块,只执行一次;每次 new 对象,先执行实例代码块,再执行构造方法。

Q:静态方法里面能不能用 this?为什么?

A:不能。this 代表当前对象引用,静态方法属于类,调用静态方法不一定需要创建对象。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 22:45:25

netdata .run可执行安装包,离线安装的方法

要进行Netdata的离线安装&#xff0c;你需要执行以下步骤&#xff1a;首先&#xff0c;从Netdata的GitHub仓库中下载最新的二进制安装包。你可以使用以下命令将其下载到你的服务器上&#xff1a;wget https://github.com/netdata/netdata/releases/latest/download/netdata-x86…

作者头像 李华
网站建设 2026/9/14 22:45:20

r2unity:Unity IL2CPP逆向分析新范式

1. 项目概述&#xff1a;r2unity不是插件&#xff0c;是Unity逆向工程的“听诊器”最近在几个Unity安全研究群和逆向技术论坛里&#xff0c;大家讨论得最多的一句话就是&#xff1a;“r2unity更新IL2CPP分析能力了”。这句话背后藏着的&#xff0c;不是某个新工具的发布&#x…

作者头像 李华
网站建设 2026/9/14 22:45:06

TDXRS作为miniQMT行情兜底方案的实战价值解析

1. 项目概述&#xff1a;当 miniQMT 的行情通道出现波动&#xff0c;为什么 TDXRS 成为实操中真正能“接得住”的备选方案最近两周&#xff0c;不少做量化交易的朋友在交流群里反复提到一个现象&#xff1a;miniQMT 的 Level-2 行情订阅偶尔出现延迟、断连或快照丢失&#xff0…

作者头像 李华
网站建设 2026/9/14 22:44:19

需求深度分析提示词-grill me

1. 精简版 # 需求深度追问模式你的任务不是立即给方案&#xff0c;而是通过逐层追问&#xff0c;把我的模糊需求收敛成明确、可执行的设计。## 核心规则1. 先用最强版本复述我的需求&#xff0c;确认你真正理解了目标。 2. 将需求拆成 3&#xff5e;6 个核心决策分支&#xff0…

作者头像 李华