目录
内容大纲:
1.本文介绍了Java中包的概念、封装特性以及static关键字和代码块的用法。
2.包(Package)是Java组织类的方式,用于防止类名冲突和提高代码可读性。
3.封装是面向对象三大特性之一,通过访问限定符(public/private/default/protected)控制成员访问权限。
4.static关键字用于修饰成员变量和方法,使其成为类成员而非实例成员。
5.代码块分为普通代码块、构造代码块和静态代码块,分别用于方法内部、实例初始化和类初始化。文章还详细讲解了包的导入、自定义包规则、封装的好处以及各种代码块的使用场景和注意事项。
一:包是什么
1.定义
(Package)是Java中⼀个组织类的⽅式,⽤于防⽌类名冲突和提⾼代码的可读性。包允许将类组织在⼀ 个层次结构中,类似于⽂件系统中的文件夹。
为了更好的管理学习过程当中的作业以及课设相关内容,分类将对应的⽂件放⼊到分类好的⽂件夹 中,就是⼀种管理⽅式

在Java中也引⼊了包,包是对类、接⼝等的封装机制的体现,是⼀种对类或者接⼝等的很好的组织⽅式
2.导⼊包中的类
java中已经提供了很多现成的类供我们使⽤.例如Date类:可以使⽤java.util.Date导⼊java.util这个包中的Date类.
java
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
//得到⼀个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
输出:

但是这种写法⽐较⿇烦⼀些,可以使⽤import语句导⼊包.
java
import java.util.Date;
class Test1 {
//引用import来导入包
public static void main(String[] args) {
//导入一个包
Date date = new Date();
//得到⼀个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
输出:

如果需要使⽤ java.util中的其他类,可以使⽤import java.util . *
java
import java.util.*;
class Test1 {
//引用import来导入包
public static void main(String[] args) {
//导入一个包
Date date = new Date();
//得到⼀个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
输出:

只要是 java.util 下的类都是可以在当前Test类中使⽤的。
但是我们更建议显式的指定要导⼊的类名.否则还是容易出现冲突的情况
java
import java.util.*;
import java.sql.*;
class Test2 {
public static void main(String[] args) {
//util 和 sql 中都存在⼀个Date 这样的类, 此时现歧义,编译出错
Date date = new Date();
//得到⼀个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
输出:

由 于java.sql.中也有⼀个Date类,此时⽆法确定到底引⼊哪个包中的类了
在这种情况下需要使⽤完整的类名
java
import java.util.*;
import java.sql.*;
class Test3 {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
//得到⼀个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
输出:

也可以使⽤import static导⼊包中静态的⽅法和字段。
java
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 30;
double y = 40;
// 静态导⼊的⽅式写起来更⽅便⼀些.
double result = sqrt(pow(x, 2) + pow(y, 2));
System.out.println(result);
}
}
输出:

注意:
sqrt 用来求平方根,pow 用来求幂(即几次方)。
3.⾃定义包
1.基本规则
1.在⽂件的最上⽅加上⼀个package语句指定该代码在哪个包中.
2.包名需要尽量指定成唯⼀的名字,通常会⽤公司的域名的颠倒形式(例如 com.bit.demo1 ).
3.包名要和代码路径相匹配.例如创建com.bit.demo1 的包,那么会存在⼀个对应的路径com/bit/demo1 来存储代码.
4.如果⼀个类没有package语句,则该类被放到⼀个默认包中.
2.使⽤IDEA创建包的过程
在IDEA中先新建⼀个包:右键src->新建->包

在弹出的对话框中输⼊包名,例如 com.bit.demo1

最终会生成三个软件包

然后我们在这里来创建我们的java类,三个软件包都可以,此时的代码中会出现package语句

package packageName; 声明⼀个包
此时可以看到我们的磁盘上的⽬录结构已经被IDEA⾃动创建出来了

3.常⻅的包
java.lang: 系统常⽤基础类 (String 、 Object), 此包从 JDK1.1 后⾃动导⼊。 java.lang.reflect:java 反射编程包 ;
java.net: 进⾏⽹络编程开发包
java.sql: 进⾏数据库开发的⽀持包。
java.util: 是 java 提供的⼯具程序包。 ( 集合类等 ) ⾮常重要
java.io:I/O 编程开发包。
4.包的访问权限控制举例
如果我们在定⼀个类的时候,如果没有指定成员变量/成员⽅法的访问权限,此时默认的访问权限就是 包访问权限。
在com.bit.demo1定义Computer类, brand属性为默认权限【包访问权限】。
java
package com.bite.demo1;
public class Computer {
//成员变量
private String cpu;
private String memory;
public String screen;
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("开机~~~");
}
public void PowerOff(){
System.out.println("关机~~~");
}
public void SurfInternet(){
System.out.println("上⽹~~~");
}
}
在com.bite.demo2中访问 Computer 中的成员
java
package com.bite.demo2;
import com.bite.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);
}
}
输出:

由于我们的screen在定义的时候用的是public来修饰的,权限是完全公开的,如果我们打印cpu以及其他的呢?
java
package com.bite.demo2;
import com.bite.demo1.Computer; //导入一个包
public class TestComputer {
public static void main(String[] args) {
Computer p = new Computer("HW", "i7", "8G", "13*14");
System.out.println(p.cpu); //报错:cup是私有的,不允许被其他类访问
System.out.println(p.brand); //报错:brand是 default,不允许被其他包中的类访问
}
}
输出:

二:封装
1.封装的概念
⾯向对象程序三⼤特性:封装、继承、多态。⽽类和对象阶段,主要研究的就是封装特性。何为封装呢?简单来说就是套壳屏蔽细节。
封装就像是把东西放在⼀个盒⼦⾥,并且控制谁可以打开这个盒⼦,以及如何使⽤盒⼦⾥的东西。在编程中,它指的是将**数据(属性)和操作这些数据的⽅法(函数)包装在⼀个单元(通常是类)**内。
⽐如:对于电脑这样⼀个复杂的设备,提供给⽤⼾的就只是:开关机、通过键盘输⼊,显⽰器,USB 插孔等,让⽤⼾来和计算机进⾏交互,完成⽇常事务

对于计算机使⽤者⽽⾔,不⽤关⼼内部核⼼部件,⽐如主板上线路是如何布局的,CPU内部是如何设 计的等,⽤⼾只需要知道,怎么开机、怎么通过键盘和⿏标与计算机进⾏交互即可。因此计算机⼚商 在出⼚时,在外部套上壳⼦,将内部实现细节隐藏起来,仅仅对外提供开关机、⿏标以及键盘插孔 等,让⽤⼾可以与计算机进⾏交互即可。
封装:将数据和操作数据的⽅法进⾏有机结合,隐藏对象的属性和实现细节,仅对外公开接⼝来和对象进⾏交互
代码实现:
java
class Student{
private String name; //使⽤private 修饰
private int age; //使⽤private 修饰
public void eat() {
System.out.println(this.name + " 正在吃饭!");
}
public void show() {
System.out.println("name: "+name+" 年龄:"+age);
}
public class Test1 {
public static void main(String[] args) {
Student stu= new Student();
}
}
上述代码使⽤private修饰 之后,在Test类中**⽆法通过stu引⽤**来进⾏访问数据,这⾥封装就起到了作⽤!
只有这两个可以访问,因为它们是public修饰的,age和name是privat修饰的,不能访问

如果要想访问,此时只能**⼿动提供get和set⽅法**作为公开的接⼝来进⾏访问!
代码实现:
java
class Student {
private String name; //使⽤private 修饰
private int age; //使⽤private 修饰
//手动引入新的成员方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//成员方法
public void eat() {
System.out.println(this.name + " 正在吃饭!");
}
public void show() {
System.out.println("name: " + name + " 年龄:" + age);
}
}
public class Test1 {
public static void main(String[] args) {
Student stu = new Student();
stu.setAge(10);
System.out.println(stu.getAge());;
}
}
输出:

注意:
导入那几个新的方法的时候,有个快捷键
在一个空处然后右键鼠标,点击生成

于是会出现对应的方法,需要什么就点哪个

封装的好处
- 降低代码的耦合性
封装可以降低对象和对象之间的耦合度,当对象内部发⽣变化时,只需要修改对象内部即可,不会影响到外部程序,因为公开的接⼝是不会发⽣改变的
- 降低代码的复杂性
封装是隐藏了对象内部的实现细节,只提供了公开的接⼝给外部,使⽤起来更加简单
- 提⾼安全性
封装可以隐藏对象的具体实现细节,阻⽌外部程序直接访问对象的内部状态,从⽽保护数据不被意外 修改或破坏
2.访问限定符详解
Java中主要通过类和访问权限来实现封装 :类可以将数据以及封装数据的⽅法结合在⼀起,更符合⼈类对事物的认知,⽽访问权限⽤来控制⽅法或者字段能否直接在类外使⽤。Java中提供了四种访问限 定符:

1.public修饰的成员变量,在所指定情况下均是可以正常访问的
2.private修饰的成员变量,只能在当前类中来使⽤
3.default表⽰什么修饰符都不加,此时只能在包当中才能被访问
4.protected的讲解我们在继承中去看
三:static关键字
static关键字可以修饰成员变量和成员⽅法。
1.static修饰成员变量
我们以Student类为例,假设有3个学⽣,他们都是在同⼀个教室上课,那么我们如何定义这个属性 呢?
如下这种⽅式定义可以吗?
java
class Student1{
private String name;
private int age;
public String classRoom;
}
public class Test2 {
public static void main(String[] args) {
Student1 stu1 = new Student1();
Student1 stu2 = new Student1();
Student1 stu3 = new Student1();
}
}
答案当然是不可以,虽然从程序⻆度出发没有报错信息,但是从设计⻆度看,是有问题的!
之前在Student类中定义的成员变量,每个对象中都会包含⼀份(称之为实例变量),因为需要使⽤这些 信息来描述具体的学⽣。⽽现在要表⽰学⽣上课的教室,这个教室的属性并不需要每个学⽣对象中都 存储⼀份,⽽是需要让所有的学⽣来共享。在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
1.使⽤static修饰该成员变量
java
class Student1{
private String name;
private int age;
public static String classRoom = "1-101";
}
public class Test2 {
public static void main(String[] args) {
Student1 stu1 = new Student1();
Student1 stu2 = new Student1();
Student1 stu3 = new Student1();
}
}
static修饰的成员变量,称为静态成员变量,静态成员变量最⼤的特性:不属于某个具体的对象,是所有对象所共享的。
【静态成员变量特性】
1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
2. 既可以通过对象访问,也可以通过类名访问,但⼀般更推荐使⽤类名访问
3. 类变量存储在⽅法区当中
4. ⽣命周期伴随类的⼀⽣(即:随类的加载⽽创建,随类的卸载⽽销毁)
2.静态成员变量的访问
我们可以通过:类名 . 静态成员变量的⽅式进⾏访问
java
class Student1{
private String name;
private int age;
public static String classRoom = "1-101";
}
public class Test2 {
public static void main(String[] args) {
//静态成员变量可以直接通过类名访问
System.out.println(Student1.classRoom);
Student1 stu1 = new Student1();
Student1 stu2 = new Student1();
Student1 stu3 = new Student1();
//也可以通过对象访问:但是 classRoom 是三个对象共享的
// System.out.println(stu1.classRoom);
// System.out.println(stu2.classRoom);
// System.out.println(stu3.classRoom);
}
}
输出:

我们也可以**通过对象来进行访问,**但是我们不建议使⽤对象的引⽤去访问静态成员变量
2.static修饰成员⽅法
Java中,被static修饰的成员⽅法称为静态成员⽅法,是类的⽅法,不是某个对象所特有的。静态成员⼀般是通过静态⽅法来访问的。
java
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. 可以通过对象调⽤,也可以通过类名.静态⽅法名(...)⽅式调⽤,更推荐使⽤后者
3. 不能在静态⽅法中访问任何⾮静态成员变量
java
class Student1{
private static String classRoom = "Bit306";
private int age;
public static String getClassRoom(){
System.out.println(this.age);
return classRoom;
}
}
public class Test2 {
public static void main(String[] args) {
System.out.println(Student1.getClassRoom());
}
}
输出:

4. 静态⽅法中不能调⽤任何⾮静态⽅法,因为⾮静态⽅法有this参数,在静态⽅法中调⽤时候⽆法传 递this引⽤
java
class Student1{
private static String classRoom = "Bit306";
private void doClass1(){
}
public static String getClassRoom(){
doClass1();
return classRoom;
}
}
public class Test2 {
public static void main(String[] args) {
System.out.println(Student1.getClassRoom());
}
}
输出:

3.static成员变量初始化
注意:静态成员变量⼀般不会放在构造⽅法中来初始化,构造⽅法中初始化的是与对象相关的实例属性
静态成员变量的初始化分为两种:就地初始化和静态代码块初始化
1.就地初始化
就地初始化指的是:在定义时直接给出初始值
public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom = "1-101";
}
2.静态代码块初始化
什么是代码块?
四:代码块
1.代码块概念以及分类
使⽤ **{ }**定义的⼀段代码称为代码块。根据代码块定义的位置以及关键字,⼜可分为以下四种:
1.普通代码块
2.构造块【有的书上叫实例代码块】
3.静态块
4.同步代码块(后续讲解多线程部分再谈)
2.普通代码块
普通代码块:定义在⽅法中的代码块
java
public class Main{
public static void main(String[] args) {
{ //直接使⽤{}定义,普通⽅法块
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
}
// 执⾏结果
x1 = 10
x2 = 100

3.构造代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块⼀般⽤于初始化实例成员变量。
java
public class Student{
//实例成员变量
private String name;
private String gender;
private int age;
private double score;
//构造方法
public Student() {
System.out.println("I am Student init()!");
}
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
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

4.静态代码块
使⽤static定义的代码块称为静态代码块。⼀般⽤于初始化静态成员变量
java
public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom;
//实例代码块
{
this.name = "bit";
this.age = 12;
this.gender = "man";
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();
}
}

注意事项:
1.静态代码块不管⽣成多少个对象,其只会执⾏⼀次
2.静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
3.如果⼀个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执⾏(合并)
4.实例代码块只有在创建对象时才会执⾏
以上就是我们的全部内容了