Java中类的访问权限

玩聚 2025-7-2 38 7/2

所谓权限,就是几个修饰符的问题。

修饰符 说明
public 公开的,任何地方都能访问
protected 受保护的,同包 + 子类可访问
默认权限 什么都不写,只能同包访问
private 私有的,只能在类内部访问

 

// src/com/example/Animal.java
package com.example;

public class Animal {
    public String name = "public";
    protected String type = "protected";
    String color = "default";
    private String secret = "private";

    public void show() {
        System.out.println(name);
        System.out.println(type);
        System.out.println(color);
        System.out.println(secret);
    }
}

同包访问,同包内访问 public / protected / default 均 OK,但 private 不行。

// src/com/example/Test.java 

package com.example;

public class Test {
    public static void main(String[] args) {
        Animal a = new Animal();
        System.out.println(a.name);   // ✅
        System.out.println(a.type);   // ✅
        System.out.println(a.color);  // ✅
        // System.out.println(a.secret); // ❌ private 无法访问
    }
}

执行编译工作

mkdir -p build
javac -d build src/com/example/Animal.java  src/com/example/Test.java

find build/

build/
build/com
build/com/example
build/com/example/Animal.class
build/com/example/Test.class

echo "Main-Class: com.example.Test" > manifest.txt
cd build
jar cfm example.jar ../manifest.txt com/example/*.class
java -jar example.jar

public
protected
default

build的时候需要进入build文件夹,这样jar文件中的package的路径和文件夹路径才能对应,也可以用 -C参数 来代替。

跨包访问(非子类),跨包只能访问 public。其他都无效。

// src/com/other/OtherTest.java

package com.other;

import com.example.Animal;

public class OtherTest {
    public static void main(String[] args) {
        Animal a = new Animal();
        System.out.println(a.name);   // ✅ public
        // System.out.println(a.type); // ❌ protected 不在子类中
        // System.out.println(a.color); // ❌ default 只能同包访问
        // System.out.println(a.secret); // ❌ private 永远不能访问
    }
}

将两个package中的class合并为一个的所需要的编译工作

echo Main-Class: com.other.OtherTest > mainfest1.txt
javac -d build src/com/other/OtherTest.java src/com/example/Animal.java
cd build
jar cfm other.jar ../manifest1.txt com/example/Animal.class com/other/OtherTest.class
java -jar other.jar

//结果:public

插播一个将Animal和OtherTest打包为独立的jar,并在一起执行的例子:

1)做一个文件夹,专门放lib类的jar,这一类的jar不需要mainfest,运行的时候指定cp(classpath)和入口函数

jar cf com.example.jar  com/example/Animal.class
jar cfm com.other.jar ../manifest1.txt  com/other/OtherTest.class

//运行方式
java -cp "com.other.jar:com.example.jar" com.other.OtherTest

2)做一个文件夹,专门放lib类的jar,这一类的jar不需要mainfest,将classpath放入manifest中,这样可以用-jar的形式来运行

 cat manifest3.txt

Main-Class: com.other.OtherTest
Class-Path: com.example.jar

 jar cfm com.other.jar manifest3.txt  com/other

//jar中没有Animal.class
jar tf com.other.jar

META-INF/
META-INF/MANIFEST.MF
com/other/
com/other/OtherTest.class

java -jar com.other.jar
public

跨包子类访问,子类中可以访问 protected 成员,即使不在同一个包。

// com.other.Dog

package com.other;

import com.example.Animal;

public class Dog extends Animal {
    public void bark() {
        System.out.println("Woof! I am a dog.");
        System.out.println("My type is: " + type); // 继承来的 protected 字段
    }
}
// com.other.OtherTest 
package com.other;

public class OtherTest {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.bark();
    }
}
javac  -cp build/com.example.jar -d build/ src/com/other/*.java

cd build
jar cfm com.other.jar manifest3.txt com/other
java -jar com.other.jar

Woof! I am a dog.
My type is: protected

 

如果什么package都不用,java中的默认包

特性 默认包(不写 package)
包名
class 文件位置 当前目录,无包结构
能否被其他包 import ❌ 不可以
是否可用作库类 ❌ 不建议,不能被复用
是否推荐在项目中使用 ❌ 不推荐,仅用于临时 demo
- THE END -

玩聚

7月03日14:36

最后修改:2025年7月3日
0

非特殊说明,文章内容整理自互联网。

共有 0 条评论