Java面向对象核心:封装、访问权限、final、静态域与静态方法详解
2026/8/6 19:50:23 网站建设 项目流程

摘要:本文结合《Java核心技术》ParamTest参数传递示例,讲解封装思想、类访问权限、私有方法、final域、静态域、静态方法、工厂方法,帮你搞懂面向对象基础重点与易错坑点。
标签:#Java #面向对象 #封装 #static #final

一、封装思想:数据隐藏

封装 = 私有数据 + 公开访问器/修改器方法
核心:将实例域私有化private,外部不能直接访问字段,只能通过类提供的get/set方法操作内部数据,保护内部状态,隔离实现与调用。

classEmployee{// 私有实例域,外部类无法直接访问privateDatehireDay;// 访问器get方法,向外返回私有字段publicDategetHireDay(){returnhireDay;}// 修改器set方法,可以在这里做参数校验publicvoidsetHireDay(DatehireDay){this.hireDay=hireDay;}}

⚠️注意坑:
如果直接返回引用类型对象return hireDay;,外部拿到对象引用可以修改对象内部属性,会破坏封装!
正确做法:返回对象副本,return new Date(hireDay.getTime());

二、基于类的访问权限

private修饰的成员:只有本类内部可以访问,不管是不是同一个对象
同一个类的不同对象,可以互相访问对方的private私有成员。

1. 私有方法 private

  • 使用private修饰方法,只允许本类内部调用。
  • 设计思路:把内部工具辅助方法私有化,对外不暴露。

如果一个方法是实现细节,不需要外部调用,就设置为private,一旦业务变更可以直接删除修改,不会影响外部调用代码。

2. final 实例域

final修饰实例域,表示引用本身不可变,但不代表引用指向的内容不可变。

  1. 基本类型final域:值完全不可修改
privatefinalintage=18;// age = 20; //编译报错,基本类型final赋值后不能修改
  1. 不可变类对象final域:对象本身不能改变状态
    比如Stringfinal String name = "张三";,name引用永远指向这个字符串,字符串本身也无法修改。

  2. 数组/可变对象的final重点易错

finalint[]arr={5,7,4,2,0};// arr = new int[3]; //❌编译报错,引用地址不能改arr[0]=100;//✅合法!数组里面元素可以修改!

关键理解:final锁住的是变量保存的地址值,不是堆里面对象/数组的内容。
final数组只是不能让arr指向另一个新数组,数组内部元素依旧可以修改。

三、静态域 static(类变量)

普通实例域:每new一个对象,就会分配一份独立的实例域内存空间,对象独有
static静态域:属于类,不属于任何实例,全类所有对象共享同一块内存,类加载完成就分配空间,不需要new对象

示例代码:

classEmployee{//静态域nextId,属于Employee类,所有对象共享这一个变量privatestaticintnextId=1;//实例域id:每个Employee对象,都有自己独立idprivateintid;}
  • 实例域:new完对象之后,堆中才开辟对象空间,才有实例域。
  • 静态域:类加载阶段就创建,不依赖对象,直接通过类名.静态变量访问。

四、静态方法 static(类方法)

静态方法属于类本身,不属于对象实例

特点

  1. 没有隐式this参数!this代表当前对象,静态方法没有对象,不能使用this
  2. 可以直接访问本类的静态域、静态方法
  3. ❌静态方法不能直接访问实例域、实例方法(实例域依赖对象)。
  4. 调用方式:类名.静态方法(),不需要new对象。

经典例子:Math.pow(x,a),Math类不需要实例化,直接调用静态方法。

//调用静态方法,不需要new Math对象doubleres=Math.pow(2,3);

什么时候写静态方法?

  1. 工具方法,不需要访问对象状态(如Math工具类)
  2. 只需要访问静态域的方法

this回顾

实例方法执行流程:

  1. 必须先new创建对象,堆开辟对象内存;
  2. 调用实例方法,隐式传入thisthis指向这个对象;
  3. 通过this访问对象实例域。

静态方法不走这套流程,没有对象,没有this。

五、工厂方法(静态工厂方法)

静态工厂方法:使用static静态方法返回类的实例对象,替代构造器new

优势

  1. 方法可以有业务语义名字,不像构造器名字固定只能是类名;
  2. 不需要每次调用都一定创建新对象,可以缓存、复用对象;
  3. 可以返回子类对象。

简单示例:

classPerson{privateStringname;//私有构造器,外部不能直接new Person()privatePerson(Stringname){this.name=name;}//工厂静态方法,对外获取实例publicstaticPersongetInstance(Stringname){returnnewPerson(name);}}//外部调用,不用new,调用工厂方法Personp=Person.getInstance("小明");

六、拓展:结合ParamTest案例理解参数传递(Java核心技术源码)

完整源码来自《Java核心技术》ParamTest.java,用来理解Java只有值传递,辅助面向对象理解。

/** * This program demonstrates parameter passing in Java. * @version 1.00 2000-01-27 * @author Cay Horstmann */publicclassParamTest{publicstaticvoidmain(String[]args){/* * Test 1: 方法不能修改基本数据类型参数 */System.out.println("Testing tripleValue:");doublepercent=10;System.out.println("Before: percent="+percent);tripleValue(percent);System.out.println("After: percent="+percent);/* * Test 2: 方法可以修改对象参数的内部状态 */System.out.println("\nTesting tripleSalary:");Employeeharry=newEmployee("Harry",50000);System.out.println("Before: salary="+harry.getSalary());tripleSalary(harry);System.out.println("After: salary="+harry.getSalary());/* * Test 3: 不能让对象参数引用指向新对象,swap交换失败 */System.out.println("\nTesting swap:");Employeea=newEmployee("Alice",70000);Employeeb=newEmployee("Bob",60000);System.out.println("Before: a="+a.getName());System.out.println("Before: b="+b.getName());swap(a,b);System.out.println("After: a="+a.getName());System.out.println("After: b="+b.getName());}//基本类型传参,副本修改,不影响外部变量publicstaticvoidtripleValue(doublex){x=3*x;System.out.println("End of method: x="+x);}//传入对象引用副本,可以修改对象内部成员publicstaticvoidtripleSalary(Employeex){x.raiseSalary(200);System.out.println("End of method: salary="+x.getSalary());}//Java值传递,swap无法交换两个外部对象publicstaticvoidswap(Employeex,Employeey){Employeetemp=x;x=y;y=temp;System.out.println("End of method: x="+x.getName());System.out.println("End of method: y="+y.getName());}}classEmployee{privateStringname;privatedoublesalary;publicEmployee(Stringn,doubles){name=n;salary=s;}publicStringgetName(){returnname;}publicdoublegetSalary(){returnsalary;}publicvoidraiseSalary(doublebyPercent){doubleraise=salary*byPercent/100;salary+=raise;}}

三个测试结论:

  1. 基本类型参数:方法拿到的是值副本,修改副本,外部变量完全不受影响。
  2. 对象参数:传递的是对象引用的副本,副本和外部变量指向同一个堆对象,方法内可以修改对象里面的成员状态。
  3. 对象引用副本重新赋值,只会改变副本,不能改变外部变量的指向,Java无法写swap交换两个对象。

七、知识点总结表格

概念修饰符核心特点
实例域无/staticnew对象之后才有内存,每个对象独立一份,实例方法可以访问
静态域static属于类,类加载就分配内存,所有对象共享,无需要实例
实例方法无/static隐式携带this,依赖对象,可以访问实例、静态成员
静态方法static没有this,不能访问实例域/实例方法,类名直接调用
final基本变量final赋值后值不能修改
final引用变量final引用地址不可修改,对象内部内容可修改
封装private + get/set私有化字段,对外暴露方法,保护内部数据
静态工厂static方法替代构造器返回实例,命名灵活、可缓存对象

八、常见面试问题

  1. final int[] arr数组元素为什么可以修改?

final锁住的是数组引用地址,不是堆内存数组内容,不能让arr指向新数组,但数组元素可改。

  1. static方法能不能使用this?

不能。静态方法属于类,不依附对象,this代表当前实例对象。

  1. Java到底是值传递还是引用传递?

Java全部是值传递。对象传递是把引用地址拷贝一份传给方法,不是传递对象本身。

  1. private修饰的方法有什么意义?

封装内部实现细节,只允许本类调用,后续维护修改不影响外部代码。

全文到此结束,希望对你理解Java面向对象基础有所帮助。


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询