Dante_7
如题, package 究竟是为了 "访问权限控制" 还是仅仅是一个分类功能? 如果是访问权限控制, 那除了接口包外的其他包都应存在同一个包下来方便访问, 如果是为了分类, 那对于包外的类来说访问其他包就和访问接口一样需要 getXXX 方法.

换个问法, 在虚拟机的实际运行中使用同一实例下的字段 id, 使用 instance.id 和 instance.getId() 在效率上有什么区别么.

新人刚学 java, 求各位 dalao 指教...



1669756340
哎,大佬大佬,编程实在难学

3TUSK
来试着回答一下这个看上去非常简单,但实际上挺棘手的问题……

两个都有——包同时起到访问级控制和分类的功能。

限定相同包内的类才能访问的两个访问级是 protected 和“没有访问级修饰符”。其中,protected 比无修饰符多允许不同包下但继承它的类访问该成员。
  1. package demo.a;

  2. public class A {
  3.   protected final int foo = 0;
  4.   final int bar = 1;
  5. }
复制代码
  1. package demo.b;

  2. import demo.a.A;

  3. public final class B extends A {
  4.   public void baz() {
  5.     System.out.println(this.foo); // 允许
  6.     //System.out.println(this.bar); // 编译器报错
  7.   }
  8. }
复制代码


分类就不用说了。如果楼主有开发基于 Bukkit 的插件的经验并知道什么是“NMS”的话,看下那个包就知道什么是“所有类塞一起”了。

除了接口包外的其他包都应该存在同一个包下来方便访问

那样不还是不同的包?就像这样:
  1. package net.mcbbs.demo.bukkit_plugin;

  2. package net.mcbbs.demo.forge_mod;

  3. package net.mcbbs.demo.sponge_plugin
复制代码

如果楼主是说真正意义上的“同一个包”:有些时候我们不希望外部代码随随便便访问甚至修改内部成员。这也是为什么我们还有一个 private 访问级(仅当前类成员允许访问该成员)的原因。

在虚拟机的实际运行中使用同一实例下的字段 id, 使用 instance.id 和 instance.getId() 在效率上有什么区别么

这和包没有关系了。
首先,只看效率的话,这个问题和你用的 JVM 有关系。有鉴于 JIT 的使用,getter/setter 如果也被识别为热点,是会被 inline 的。此时的效率和 native code 无异,也就无所谓 instance.id 和 instance.getId() 的差别了。
跑一下题。抛开效率不谈,instance.getId() 的写法比 instance.id 的写法更符合 OOP 的设计原则(具体来说是封装,encapsulation)。此时“id”也会被称作是“属性”(property)。考虑下面这个例子:
  1. public class MyFurnace {
  2.   private int workingProgress = 0;
  3.   // 对外界来说,它看上去也是一个 getter
  4.   // 但实际上根本没有 private boolean isWorking 这个字段。
  5.   public boolean isWorking() {
  6.     return this.workingProgress > 0;
  7.   }
  8.   public int getWorkingProgress() {
  9.     return this.workingProgress;
  10.   }
  11.   public void setWorkingProgress(int newProgress) {
  12.     this.workingProgress = newProgress;
  13.   }
  14. }
复制代码


有问题请跟进。

BobPlayer
本帖最后由 浅念哥 于 2019-5-12 19:07 编辑
尽可能使用局部变量

调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中速度较快,其他变量,如静态变量、实例变量等,都在堆中创建,速度较慢。另外,栈中创建的变量,随着方法的运行结束,这些内容就没了,不需要额外的垃圾回收。

"访问权限控制"是package的作用,"分类功能"是对package的命名规范。

参考:
https://en.wikipedia.org/wiki/Java_package
https://en.wikipedia.org/wiki/Namespace
https://www.kancloud.cn/digest/javabug/138399




1723624171
用export出口打包吧

liach
1、包主要是分类,当然也有访问权限控制的功能(包私有 package private)。访问权限控制主要是将一些不需要暴露的实现声明为包私有 package private(即没有 private protected 或 public 声明),只有同一个包里面的代码才能调用。但是大多数时候还是用来分类代码的。

2、直接使用字段肯定比使用方法快(少呼叫一次方法),但是你 id 是内部类私有变量的情况下除外(这种情况下,java11前会在每个使用字段的地方生成一个包私有的方法,导致性能下降;java 11以后不会了)