作用域

定义为publicclassinterface可以被其他任何类访问:

上面的Hellopublic,因此,可以被其他包的类访问:

  1. package xyz;
  2. class Main {
  3. void foo() {
  4. // Main可以访问Hello
  5. Hello h = new Hello();
  6. }
  7. }

定义为publicfieldmethod可以被其他类访问,前提是首先有访问class的权限:

  1. package abc;
  2. public class Hello {
  3. public void hi() {
  4. }
  5. }

上面的hi()方法是public,可以被其他类调用,前提是首先要能访问Hello类:

  1. package xyz;
  2. class Main {
  3. void foo() {
  4. Hello h = new Hello();
  5. h.hi();
  6. }
  7. }

private

定义为privatefieldmethod无法被其他类访问:

  1. package abc;
  2. public class Hello {
  3. // 不能被其他类调用:
  4. private void hi() {
  5. public void hello() {
  6. this.hi();
  7. }
  8. }

实际上,确切地说,private访问权限被限定在class的内部,而且与方法声明顺序无关。推荐把private方法放到后面,因为public方法定义了类对外提供的功能,阅读代码的时候,应该先关注public方法:

由于Java支持嵌套类,如果一个类内部还定义了嵌套类,那么,嵌套类拥有访问private的权限:

定义在一个内部的class称为嵌套类(nested class),Java支持好几种嵌套类。

protected

protected作用于继承关系。定义为protected的字段和方法可以被子类访问,以及子类的子类:

  1. package abc;
  2. public class Hello {
  3. // protected方法:
  4. protected void hi() {
  5. }
  6. }

上面的protected方法可以被继承的类访问:

  1. package xyz;
  2. class Main extends Hello {
  3. void foo() {
  4. Hello h = new Hello();
  5. // 可以访问protected方法:
  6. h.hi();
  7. }
  8. }
  1. package abc;
  2. // package权限的类:
  3. class Hello {
  4. // package权限的方法:
  5. void hi() {
  6. }
  7. }

只要在同一个包,就可以访问package权限的classfieldmethod

  1. package abc;
  2. class Main {
  3. void foo() {
  4. // 可以访问package权限的类:
  5. Hello h = new Hello();
  6. // 可以调用package权限的方法:
  7. h.hi();
  8. }

注意,包名必须完全一致,包没有父子关系,com.apachecom.apache.abc是不同的包。

局部变量

在方法内部定义的变量称为局部变量,局部变量作用域从变量声明处开始到对应的块结束。方法参数也是局部变量。

我们观察上面的hi()方法代码:

  • 方法参数name是局部变量,它的作用域是整个方法,即①~⑩;

  • 变量s的作用域是定义处到方法结束,即②~⑩;

  • 变量len的作用域是定义处到方法结束,即③~⑩;

  • 变量p的作用域是定义处到if块结束,即⑤~⑨;

  • 变量i的作用域是for循环,即⑥~⑧。

使用局部变量时,应该尽可能把局部变量的作用域缩小,尽可能延后声明局部变量。

final

Java还提供了一个final修饰符。final与访问权限不冲突,它有很多作用。

  1. // 无法被继承:
  2. public final class Hello {
  3. private int n = 0;
  4. protected void hi(int t) {
  5. long i = t;
  6. }
  7. }

final修饰method可以阻止被子类覆写:

  1. package abc;
  2. public class Hello {
  3. // 无法被覆写:
  4. protected final void hi() {
  5. }
  6. }

final修饰field可以阻止被重新赋值:

  1. package abc;
  2. public class Hello {
  3. private final int n = 0;
  4. protected void hi() {
  5. this.n = 1; // error!
  6. }
  7. }

final修饰局部变量可以阻止被重新赋值:

  1. package abc;
  2. public class Hello {
  3. protected void hi(final int t) {
  4. t = 1; // error!
  5. }

如果不确定是否需要public,就不声明为public,即尽可能少地暴露对外的字段和方法。

把方法定义为package权限有助于测试,因为测试类和被测试类只要位于同一个package,测试代码就可以访问被测试类的package权限方法。

一个.java文件只能包含一个public类,但可以包含多个非public类。如果有public类,文件名必须和public类的名字相同。

小结

Java内建的访问权限包括publicprotectedprivatepackage权限;

Java在方法内部定义的变量是局部变量,局部变量的作用域从变量声明开始,到一个块结束;

final修饰符不是访问权限,它可以修饰classfieldmethod

一个.java文件只能包含一个public类,但可以包含多个非public类。

读后有收获可以支付宝请作者喝咖啡,读后有疑问请加微信群讨论

作用域 - 图1