浅析Java中的访问控制权限

Java中为什么要设计访问权限控制机制呢?主要作用有两点:

(1)为了使用户不要触碰那些他们不该触碰的部分,这些部分对于类内部的操作时必要的,但是它并不属于客户端程序员所需接口的一部分。

(2)为了让类库设计者可用更改类的内部工作方式,而不必担心会对用户造成重大影响。

Java中的访问权限控制的等级,按照权限从大到小依次为:

Public -> protected -> 包访问权限(没有权限修饰词)-> private。

 一、包(package)

Java中包(package)的概念和C++中命名空间(namespace)的概念很类似,都可以限制类的作用域。二者最大的差别在于,Java中的包隐式地指明了类的树形层级结构(同时也是Java源码文件的目录结构)。这样做的好处在于:可以通过文件系统中对于文件路径唯一性的要求来限制类的唯一性。

 1、代码组织

编写一个Java源代码文件(.java文件)时,此文件通常被称为编译单元。在编译单元内最多允许有一个public类,且该类的名称必须与文件名完全相同(包括大小写)。

编译一个.java文件时,在.java文件中的每个类都会有一个.class输出文件,这个文件名和类名是相同的。Java可运行程序是一组可以打包并压缩为一个Java文档文件(JAR包,使用Java的jar文档生成器)的.class文件。Java解释器负责这些文件的查找、装载和解释。

类库实际上是一组类文件。其中每个.java文件最多允许有一个public类,以及任意数量的非public类。因此,每个文件都有一个构件。如果要将这些构件(每个构建有一个.java文件和若干个.class文件)组织起来,形成不同的群组,可以使用Java中的关键字package。

 2、包(package)的作用

(1)     把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。

(2)     如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。

(3)     包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

 3、创建包

Java中,使用package关键字来指定代码所属的包(命名空间)。

语法格式:

package pkg1[.pkg2[.pkg3…]];

注意点:

(1)     包的名字隐含地指出了代码的目录结构。

(2)     同一目录下的public类名(同时也是java文件名)应该是独一无二的。

(3)     包声明应该在源文件的第一行,每个源文件只能有一个包声明,这个文件中的每个类型都应用于它。

(4)     如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中。

(5)     package的名字一般全是小写字母。

例如:

查看java.util.ArrayList类的源码可以看到文件第一行代码为:

package java.util;

它的代码目录结构就是java/util/ArrayList.java

 4、导入包

Java中,使用import关键字来导入包。

语法格式:

import package1[.package2…].(classname|*);

例:

还是以java.util.ArrayList来举例。如果以一个了类完整路径的方式来使用它,十分不方便。

java.util.ArrayList<String> list = new java.util.ArrayList<String>();

如果想要省略前面的路径,可以使用import关键字。

import java.util.ArrayList;

文件中使用了import导入包后,前面的声明list的代码就可以简化如下:

ArrayList<String> list = new ArrayList<String>();

二、访问权限修饰词

1、package:包访问权限

如果不提供任何访问权限修饰词,则意味着它是包访问权限。

默认访问权限没有任何关键字,但通常是指包访问权限(有时也表示为friendly,有点像C++中的友元概念)。这意味着包中所有其他类都可以访问这个成员或方法,但是这个包之外的所有类不可以访问。

例:

com.notes.packages.test.Info

package com.notes.packages.test;

publicclass Info {

  void print() { System.out.println("default method -- print()"); }

}

com.notes.packages.test.PublicDemo01

package com.notes.packages.test;

publicclass PublicDemo01 {

  publicstaticvoid main(String[] args) {

    Info x = new Info();

    x.print();

  }

}

PublicDemo01和Info在同一个包下,可以访问Info的default级别的方法——print()。

com.notes.packages.PublicDemo02

package com.notes.packages;

import com.notes.packages.test.Info;

publicclass PublicDemo02 {

  publicstaticvoid main(String[] args) {

    Info x = new Info();

    // x.print(); // Error

  }

}

PublicDemo02和Info不在一个包下,不可以访问Info的包访问权限级别的方法——print()。

 2、public:接口访问权限

使用public关键字,就意味着被声明的成员或方法对所有人都是可以访问的。

例:如果将default级别权限例子中的print()方法权限设为public,则PublicDemo02可以访问。

package com.notes.packages.test;

publicclass Info {

  publicvoid print() { System.out.println("public method -- print()"); }

}

3、private:无法访问

使用private关键字,就意味着被声明的成员或方法,除了本类,其他任何类都无法访问。

应用场景:单例模式

 4、protected:继承访问权限

新类(称之子类或派生类)通过继承可以复用一个现有类(称之父类或基类),然后扩展基类的成员、方法。有时,基类的创建者会希望某个特定成员,将它的访问权限赋予派生类而不是所有类。public无法做到这一点,为此,引入了protected来完成这一工作。protected也提供包访问权限,也就是说,派生类以及相同包内的其他类都可以访问protected成员或方法。

例:子类继承父类后,可以访问父类的protected成员。

class Father {

  private String a = "private";

  protected String b = "protected";

  public String c = "public";

};

class Son extends Father {

  publicvoid print() {

    // System.out.println("element a:" + super.a); // Error

    System.out.println("element b:" + super.b);

    System.out.println("element c:" + super.c);

  }

}

publicclass ProtectedDemo01 {

  publicstaticvoid main(String args[]) {

    Son sub = new Son();

    sub.print();

  }

};

访问权限修饰词的注意点

前面各个例子中展示了类的成员、方法都可以用各种权限修饰词来修饰。

除此之外,还有一些需要注意的点:

(1)     静态成员、静态方法的权限修饰词的用法和普通成员、方法一样。

(2)     类虽然也可以被修饰词修饰,但是不可以用private、protected两个权限修辞词。

(3)     有些书中将包访问权限又叫做默认访问权限。个人不建议这么去记,因为这很容易与Java Se8中新特性——default关键字混淆。这个关键字只能用于Interface,作用是允许程序员在Interface中定义接口的默认具体实现(以往的JDK版本是不允许这样的,你只能在接口中声明方法)。

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

(0)

相关推荐

  • java类访问权限与成员访问权限解析

    在写代码的时候有个问题:包内定义了一个接口类,另外一个包要实现它,这里采用接口隔离与依赖倒置原则,将两个包的依赖关系倒置过来.但是,这里就遇到了一个问题,实现类采用工厂模式来实例化,所以实现类就不想暴露给包外,但是实现类还要实现public接口.所以这里有产生了一个疑问,如果类是default类型,成员函数是public类型,那么访问限制是怎样的呢? 实现验证 1. 先在一个包中定义一个接口类: package mytest public interface ClassAccessTest {

  • Java中的访问修饰符详细解析

    1.类的修饰符分为:可访问控制符和非访问控制符两种. 可访问控制符是:公共类修饰符 public 非访问控制符有:抽象类修饰符 abstract :最终类修饰符 final 1 )公共类修饰符 public : Java 语言中类的可访问控制符只有一个: public 即公共的.每个 Java 程序的主类都必须是 public 类作为公共工具供其它类和程序使用的应定义为 public 类. 2 )抽象类修饰符 abstract :凡是用 abstract 修饰符修饰的类,被称为抽象类.所谓抽象类

  • 理解Java访问权限控制

    今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制.考虑两个场景: 场景1:工程师A编写了一个类ClassA,但是工程师A并不希望ClassA被该应用中其他所用的类都访问到,那么该如何处理? 场景2:如果工程师A编写了一个类ClassA,其中有两个方法fun1.fun2,工程师只想让fun1对外可见,也就是说,如果别的工程师来调用ClassA,只可以调用方法fun1,那么该怎么处理? 此时,访问权限控制便可以起到作用了. 在Java中,提

  • 封装了一个Java数据库访问管理类

    复制代码 代码如下: package com.groundhog.codingmouse; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * 数据库管理类 * @author CodingMouse * 2009.2.20 */ pub

  • JavaMail访问Hotmail邮箱

    相信许多人都有MSN聊天工具的帐号,例如abc@hotmail.com ,这个账号其实也是一个邮件地址,可以进行正常的邮件收发功能,你可以通过网址 http://www.hotmail.com 来访问和操作这个邮箱进行邮件的收发.但是这个邮箱有一个限制就是它并不提供POP3或者SMTP服务,也就是说一般的邮件客户端工具无法使用这个邮箱,虽然现在有不少的邮件工具可以支持Hotmail邮箱,但是如果我们需要在我们的Java项目中增加对Hotmail邮箱的支持,那往往会不知从什么地方开始入手,因为SU

  • 基于JQuery的访问WebService的代码(可访问Java[Xfire])

    我仔细看看了看看几个人的例子,发现了问题.众所周知WebService是遵守SOAP协议的,为什么例子都是JSON格式的参数传递?net WebService兼容JSON格式,而Java的是标准WebService,不兼容JSON.看来net害了大家啊.于是我仔细了解了WSDL文件,做了个例子.下面只放关键代码. 复制代码 代码如下: $(function () { $("#btnWs").click(btnAjaxPost); }); function btnAjaxPost(eve

  • Java中成员方法与成员变量访问权限详解

    记得在一次面试的笔试题中,有的面试官会要求写出具体的像pullic这些访问限定符的作用域.其实,平常我都没去系统的考虑这些访问限定符的作用域,特别是包内包外的情况,OK,笔试不行了. 这是java基本的知识,也是公司看重的,那没办法啦,我的脑袋记不住东西,那我只能把这些东西写下来方便自己温故知新,不废话了,贴代码了. 代码如下: package com.jaovo; /** *_1_ 成员变量访问权限的求证 * public private protected default(默认的权限) *自

  • 举例详解Java中的访问权限修饰符

    访问权限符: (1)public: 对于成员来说:任何其他类都可以访问它们,不管在同一个包中还是在另外的包中. 对于类来说:    也是一样. (2)friendly: 对于成员老说:如果一个类的成员没有任何权限修饰,那么它门就是缺省包访问权限,用friendly来表示,注 意friendly不是Java中的关键字,这里是个人喜欢的方式用它表示而已.同一个包内其它类可以访问,但包外 就不可以.对于同一个文件夹下的.没有用package的classes,Java会自动将这些classes初见为隶属

  • 浅析Java中的访问控制权限

    Java中为什么要设计访问权限控制机制呢?主要作用有两点: (1)为了使用户不要触碰那些他们不该触碰的部分,这些部分对于类内部的操作时必要的,但是它并不属于客户端程序员所需接口的一部分. (2)为了让类库设计者可用更改类的内部工作方式,而不必担心会对用户造成重大影响. Java中的访问权限控制的等级,按照权限从大到小依次为: Public -> protected -> 包访问权限(没有权限修饰词)-> private.  一.包(package) Java中包(package)的概念和

  • 浅析java修饰符访问权限(动力节点Java学院整理)

    Java有四种访问权限,其中三种有访问权限修饰符,分别为private,public和protected,还有一种不带任何修饰符: 1. private: Java语言中对访问权限限制的最窄的修饰符,一般称之为"私有的".被其修饰的类.属性以及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问. 2. default:即不加任何访问修饰符,通常称为"默认访问模式".该模式下,只允许在同一个包中进行访问. 3. protect: 介于public 和 pri

  • 深入了解Java包与访问控制权限

    目录 1.包的概念及使用 (1)基本概念 (2)import 语句 (3)系统常见包 (4)Java 新特性 – 静态导入 2.jar命令的使用 3.访问控制权限 private访问权限 default(默认)访问权限 protected访问权限 public访问权限 4.Java命名规范 1.包的概念及使用 (1)基本概念 package是在使用多个类或接口时,为了避免名称重复而采用的一种措施,直接在程序中加入package关键字即可 格式如下: package 包名称.子包名称; 范例: p

  • 浅析java中stringBuilder的用法

    String对象是不可改变的.每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需要对字符串执行重复修改的情况下,与创建新的 String对象相关的系统开销可能会非常昂贵.如果要修改字符串而不创建新的对象,则可以使用System.Text.StringBuilder类.例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder类可以提升性能. 通过用一个重载的构造函数方法初始化变量,可以创建 Strin

  • java中的通用权限管理设计(推荐)

    实现业务系统中的用户权限管理 B/S系统中的权限比C/S中的更显的重要,C/S系统因为具有特殊的客户端,所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检测实现,而B/S中,浏览器是每一台计算机都已具备的,如果不建立一个完整的权限检测,那么一个"非法用户"很可能就能通过浏览器轻易访问到B/S系统中的所有功能.因此B/S业务系统都需要有一个或多个权限系统来实现访问权限检测,让经过授权的用户可以正常合法的使用已授权功能,而对那些未经授权的"非法用户"将会将他

  • 浅析java中String类型中“==”与“equal”的区别

    一.前言 1.1.首先很多人都知道,String中用"=="比较的是地址,用equals比较的是内容,很多人对此用的是记忆法,通过记忆来加强此的引用,但是其真正的原理其实并不难,当我们真正明白其为什么的时候,用起来也会更加灵活,更加有底气(形容得不太好,朋友别见怪): 二相关知识的准备 类型常量池 运行时常量池 字符串常量池 我们今天讨论的主题是当然是字符串常量池: 为什么在这要把另外两个常量池拿出说一下呢,首先小生我在网上或者cnds上看到很多人在争论字符串常量池是存在与方法区还是堆

  • 浅析Java中Apache BeanUtils和Spring BeanUtils的用法

    # 前言 在我们实际项目开发过程中,我们经常需要将不同的两个对象实例进行属性复制,从而基于源对象的属性信息进行后续操作,而不改变源对象的属性信息,比如DTO数据传输对象和数据对象DO,我们需要将DO对象进行属性复制到DTO,但是对象格式又不一样,所以我们需要编写映射代码将对象中的属性值从一种类型转换成另一种类型. # 对象拷贝 在具体介绍两种 BeanUtils 之前,先来补充一些基础知识.它们两种工具本质上就是对象拷贝工具,而对象拷贝又分为深拷贝和浅拷贝,下面进行详细解释. # 什么是浅拷贝和

  • 浅析Java中的异常处理机制

    异常处理机制 1.抛出异常 2.捕获异常 3.异常处理五个关键字: try.catch.finally.throw.throws 注意:假设要捕获多个异常:需要按照层级关系(异常体系结构) 从小到大! package exception; /** * Java 捕获和抛出异常: * 异常处理机制 * 1.抛出异常 * 2.捕获异常 * 3.异常处理五个关键字 * try.catch.finally.throw.throws * 注意:假设要捕获多个异常:需要按照层级关系(异常体系结构) 从小到大

  • 浅析JAVA中的内存结构、重载、this与继承

    一.对象在JVM的内存结构 JAVA内存管理由JVM来管理. 1)堆,所有new出来的对象(包括成员变量) 2)栈,所有局部变量(包括方法的参数) 3)方法区,class字节码文件(包括方法,静态数据) 1.引用变量指向null时,会发生空指针异常 public class student { int age; String name; public student(int age,String name){ this.age=age; this.name=name; } public stat

  • 浅析java中Pair和Map的区别

    在这篇文章中,我们讨论了一个非常有用的编程概念,配对(Pair).配对提供了一种方便方式来处理简单的键值关联,当我们想从方法返回两个值时特别有用. 在核心Java库中可以使用配对(Pair)的实现.除此之外,某些第三方库,比如Apache Commons和Vavr,已经在各自的api中公开了这个功能. 核心java配对实现 Pair类 Pair类在javafx.util 包中,类构造函数有两个参数,键及对应值: Pair<Integer, String> pair = new Pair<

随机推荐