理解Java访问权限控制

 更新时间:2016年02月16日 10:48:34   作者:海 子  
这篇文章主要帮助大家深入的理解Java访问权限控制,为何需要访问控制权限,本文给出了解释,感兴趣的小伙伴们可以参考一下

今天我们来一起了解一下Java语言中的访问权限控制。在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制。考虑两个场景:

  场景1:工程师A编写了一个类ClassA,但是工程师A并不希望ClassA被该应用中其他所用的类都访问到,那么该如何处理?

  场景2:如果工程师A编写了一个类ClassA,其中有两个方法fun1、fun2,工程师只想让fun1对外可见,也就是说,如果别的工程师来调用ClassA,只可以调用方法fun1,那么该怎么处理?

  此时,访问权限控制便可以起到作用了。

  在Java中,提供了四种访问权限控制:默认访问权限(包访问权限),public,private以及protected。

  注意,上述四种访问权限,只有默认访问权限和public能够用来修饰类。修饰类的变量和方法四种权限都可以。(本处所说的类针对的是外部类,不包括内部类)

  下面就分别针对修饰类和修饰类的成员来讲述这四种访问权限控制。

1.修饰类

  默认访问权限(包访问权限):用来修饰类的话,表示该类只对同一个包中的其他类可见。

  public:用来修饰类的话,表示该类对其他所有的类都可见。

  下面通过几个例子来看一下两者的区别:

例1:

Main.java:

package com.cxh.test1;
 
 
public class Main {
 
  /**
   * @param args
   */
  public static void main(String[] args) {
    // TODO Auto-generated method stub
     
    People people = new People("Tom");
    System.out.println(people.getName());
  }
 
}

People.java

package com.cxh.test1;
 
class People {      //默认访问权限(包访问权限)
 
  private String name = null;
   
  public People(String name) {
    this.name = name;
  }
   
  public String getName() {
    return name;
  }
   
  public void setName(String name) {
    this.name = name;
  }
}

  从代码可以看出,修饰People类采用的是默认访问权限,而由于People类和Main类在同一个包中,因此People类对于Main类是可见的。

  程序运行结果:

  

例子2:

People.java

package com.cxh.test2;
 
class People {      //默认访问权限(包访问权限)
 
  private String name = null;
   
  public People(String name) {
    this.name = name;
  }
   
  public String getName() {
    return name;
  }
   
  public void setName(String name) {
    this.name = name;
  }
}

  此时People类和Main类不在同一个包中,会发生什么情况呢?

  下面是Main类中的提示的错误:

  

  提示Peolple类在Main类中不可视。从这里就可以看出,如果用默认访问权限去修饰一个类,该类只对同一个包中的其他类可见,对于不同包中的类是不可见的。

  正如上图的快速修正提示所示,将People类的默认访问权限更改为public的话,People类对于Main类便可见了。

2.修饰类的方法和变量

  默认访问权限(包访问权限):如果一个类的方法或变量被包访问权限修饰,也就意味着只能在同一个包中的其他类中显示地调用该类的方法或者变量,在不同包中的类中不能显示地调用该类的方法或变量。

  private:如果一个类的方法或者变量被private修饰,那么这个类的方法或者变量只能在该类本身中被访问,在类外以及其他类中都不能显示地进行访问。

  protected:如果一个类的方法或者变量被protected修饰,对于同一个包的类,这个类的方法或变量是可以被访问的。对于不同包的类,只有继承于该类的类才可以访问到该类的方法或者变量。

  public:被public修饰的方法或者变量,在任何地方都是可见的。

下面再通过几个例子来看一下它们作用域类的方法和变量时的区别:

例3:

Main.java没有变化

People.java

package com.cxh.test1;
 
public class People {   
 
  private String name = null;
   
  public People(String name) {
    this.name = name;
  }
   
  String getName() {  //默认访问权限(包访问权限)
    return name;
  }
   
  void setName(String name) {  //默认访问权限(包访问权限)
    this.name = name;
  }
}

  此时在Main类是可以显示调用方法getName和setName的。

但是如果People类和Main类不在同一个包中:

package com.cxh.test2;  //与Main类处于不同包中
 
public class People {   
 
  private String name = null;
   
  public People(String name) {
    this.name = name;
  }
   
  String getName() {  //默认访问权限(包访问权限)
    return name;
  }
   
  void setName(String name) {  //默认访问权限(包访问权限)
    this.name = name;
  }
}

  此时在Main类中会提示错误:

  

  由此可以看出,如果用默认访问权限来修饰类的方法或者变量,则只能在同一个包的其他类中进行访问。

 例4:

People.java

package com.cxh.test1;  
 
public class People {   
 
  private String name = null;
   
  public People(String name) {
    this.name = name;
  }
   
  protected String getName() {  
    return name;
  }
   
  protected void setName(String name) { 
    this.name = name;
  }
}

  此时是可以在Main中显示调用方法getName和setName的。

如果People类和Main类处于不同包中:

package com.cxh.test2;  
 
public class People {   
 
  private String name = null;
   
  public People(String name) {
    this.name = name;
  }
   
  protected String getName() {  
    return name;
  }
   
  protected void setName(String name) { 
    this.name = name;
  }
}

  则会在Main中报错:

  

  如果在com.cxh.test1中定一个类Man继承People,则可以在类Man中显示调用方法getName和setName:

package com.cxh.test1;
 
import com.cxh.test2.People;
 
public class Man extends People{
 
  public Man(String name){
    super(name);
  }
   
  public String toString() {
    return getName();
  }
}

  下面补充一些关于Java包和类文件的知识:

  1)Java中的包主要是为了防止类文件命名冲突以及方便进行代码组织和管理;

  2)对于一个Java源代码文件,如果存在public类的话,只能有一个public类,且此时源代码文件的名称必须和public类的名称完全相同,另外,如果还存在其他类,这些类在包外是不可见的。如果源代码文件没有public类,则源代码文件的名称可以随意命名。

以上就是本文的全部内容,希望对大家的学习有所帮助。

相关文章

  • java多线程通过CompletableFuture组装异步计算单元

    java多线程通过CompletableFuture组装异步计算单元

    这篇文章主要为大家介绍了java多线程通过CompletableFuture组装异步计算单元,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • PageHelper在springboot中的使用方式

    PageHelper在springboot中的使用方式

    这篇文章主要介绍了PageHelper在springboot中的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Spring Security前后分离校验token的实现方法

    Spring Security前后分离校验token的实现方法

    这篇文章主要介绍了Spring Security前后分离校验token的方法,本次token生成采取jwt的方式,通过引入jwt依赖文件配置token管理器,对Spring Security校验token相关知识感兴趣的朋友一起看看吧
    2022-02-02
  • java调用webservice接口,并解析返回参数问题

    java调用webservice接口,并解析返回参数问题

    这篇文章主要介绍了java调用webservice接口,并解析返回参数问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • kotlin和Java的相互调用示例详解

    kotlin和Java的相互调用示例详解

    Kotlin 的设计过程中就考虑到了与 Java 的互操作性。在 Kotlin 中可以直接调用既有的 Java 代码, 反过来在 Java 中也可以很流畅地使用 Kotlin 代码,下面这篇文章主要给大家介绍了关于kotlin和Java的相互调用的相关资料,需要的朋友可以参考下。
    2018-02-02
  • Java 17新特性详细讲解与代码实例

    Java 17新特性详细讲解与代码实例

    这篇文章主要给大家介绍了关于Java 17新特性详细讲解与代码实例的相关资料,Java 17是2021年9月发布的最新版本,其中包含了很多新特性和改进,这些新特性和改进将进一步提高 Java 语言的性能和可用性,需要的朋友可以参考下
    2023-09-09
  • Java current并发包超详细分析

    Java current并发包超详细分析

    current并发包、在JDK1.5之前Java并没有提供线程安全的一些工具类去操作多线程,需要开发人员自行编写实现线程安全,但仍然无法完全避免低性能、死锁、资源管理等问题。在JDK1.5时新增了java.util.current并发包,其中提供了许多供我们使用的并发编程工具类
    2023-02-02
  • 有关ServletConfig与ServletContext的访问

    有关ServletConfig与ServletContext的访问

    下面小编就为大家带来一篇有关ServletConfig与ServletContext的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 详解如何使用IntelliJ IDEA新建一个Servlet项目

    详解如何使用IntelliJ IDEA新建一个Servlet项目

    这篇文章主要介绍了详解如何使用IntelliJ IDEA新建一个Servlet项目,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • 图书管理系统java代码实现

    图书管理系统java代码实现

    这篇文章主要为大家详细介绍了java代码实现的图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01

最新评论