cs61b|cs61b week6 -- Packages and Access Control
1.Packages
在Java中,Packages是管理class和interface的命名空间(namespace),包名与网站名正好相反,比如:
ug.joshh.animal;
则对应的网站应该是:
joshh.ug
包名与文件夹路径的对应关系:
ug.joshh.animal 对应 ug/joshh/animal
使用Packages的好处是支持不同包内可以有同名的class文件,而不会混淆
1.1在Intellij IDEA中创建Packages 【cs61b|cs61b week6 -- Packages and Access Control】参考Creating a Package in IntelliJ
比较详细
简单来说,在Intellij IDEA中的操作即
File-->New-->Packages-->输入包名(ug.joshh.animal)
1.2使用Packages 如果Dog.class所在的Packages为ug.joshh.animal,则在包外使用Dog.class的话,需要声明规范名称,即
ug.joshh.animal.Dog d = new ug.joshh.animal.Dog(...);
也可以简写,前提是在文件顶部声明 import ug.joshh.animal.Dog;
就可以简写为:
Dog d = new dog();
1.3 Default Packages 任何在文件顶部没有显式包名的 Java 类都会自动被视为Default Packages的一部分。
文章图片
如图所示,所有非 ug.joshh.animal 包的class文件均视为Default Packages
在实际开发中应该避免使用Default Packages,因为Default Packages不能被import,因此在Default Packages下很有可能创建相同类名的文件
1.4 .jar文件 假如你想与某人分享你的某个project的所有.class文件,可以将其打包为.jar文件,相当于.zip文件,只不过前者拥有一些额外的信息。
在Intellij IDEA中打包的方法为:
1.) Go to File → Project Structure → Artifacts → JAR → “From modules with dependencies”2.) Click OK a couple of times3.) Click Build → Build Artifacts (this will create a JAR file in a folder called “Artifacts”)4.) Distribute this JAR file to other Java programmers, who can now import it into IntelliJ (or otherwise)
参考JAR Files
.jar文件并不能保障你的代码安全,因为其实质与.zip差不多,只需将其解压为.class文件,之后可以轻松将.class文件还原为.java文件
2.Access Modifiers
文章图片
以上列出了不同修饰符(public protected private 与"packages private")之间的访问控制,其中黑色方块代表packages private类型,即在声明变量前不加任何修饰符,则该变量自动成为本包的私有变量,只有本包内的文件与同类可以访问,在外包的extends的子类也不能访问!
再次补充关于Defalut Packages
事实上在我们没有学习Packages之前,我们创建的文件均相当于在默认包内,没有包声明的代码自动成为默认包的一部分。
如果这些类的成员没有访问修饰符,那么成员的默认类型为packages private类型,因为所有的文件都是同一个默认包的一部分,这些成员在包内的不同class之间可以访问,这就是我们之前在未了解Packages之前为何代码能够良好运行的原因。
访问控制仅限于静态类型 上面我们说如果在同一个包内,不声明访问修饰符的变量,其默认类型是package private,但是对于 Interface 来说,如果其成员不声明访问修饰符,其默认类型是 public
除此之外,其他情况均如副标题所述 (the access depends only on the static types.)
小练习
文章图片
观察上图代码,判断在Client class中的每一行是否能够正常编译,其中 BlackHole 和 CreationUtils 和 HasHair 位于同一个包universe内,而class Client位于默认包内。
主要分析编译错误的两行代码
1. b.get(0);
b的静态类型是 BlackHole ,编译时编译器检查 BlackHole 是否有 get() 方法--没有,编译错误
2. HasHair hb = (HasHair) b;
按道理来说,当我们使用强制类型转换之后,编译器会忽视b原本的类型,而直接通过编译,但是在此处,由于 HasHair 是位于 package universe内的,且整个class未声明访问修饰符,因此 HasHair class 实际上是 package private 类型,因此在默认包中无法访问,因为默认包对于 universe包来说相当于外包了。
文章图片
推荐阅读
- cs61b week8 -- Binary Search Tree
- cs61b week8 -- Disjoint Sets
- cs61b week7 -- Asymptotics ||
- No local packages or working download links found for pbr
- Chapter|Chapter 7. Packages
- 关于flutter flutter pub get 或 flutter packages get 下载慢的解决方案
- flutter packages get - pub get failed (1)解决方案
- cs61b week7 -- Asymptotics I
- 小白探索|解决Running "flutter packages get" in flutter_first_app...卡住 问题
- Learning R 17 - Making Packages