Java 访问控制权限

Posted 莫西里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 访问控制权限相关的知识,希望对你有一定的参考价值。

一、介绍

访问控制权限控制客户端对类的访问权限,提供给客户端不同权限的接口,对整个程序结构和接口与实现都进行支持。

二、详解

1、包

包(Package)基本上写过java语言都熟悉package是什么。package的主要作用,是对类提供一个命名空间。程序员可以将多个类文件放置到同一个package下来组织这些类文件关系。我们可以说一个类是由package+className实现了一个类的唯一标示。

(1)包的声明与使用

因为一个类的可以说是由package加上类文件组成,因此我们在定义一个类是需要类的包定名,也就是给类声明一个命名空间。因此我们在类的第一行代码进行包声明:

package com.wozipa.study.java.access;

包在声明过程中,需要注意的点:
1、使用关键字package声明Java类的package
2、package的声明过程中全部小写
3、package当出现层次关系式,使用点来表示,子包文件夹

当我们使用一个已经定义好的类是,需要使用类全限定名(package + classname)来引入一个类文件。当然我们也可以批量引入某一个包中的所有类。

import com.wozipa.study.java.access.PackageTests;
import com.wozipa.study.java.access.*;

(2)包在类加载时的作用

我们在开发过程中,编译后一个类文件中所有的类定义都会生成一个.class文件,最终我们会将所有的.class文件打包生成一个Jar文件。
当我们在使用一个Jar文件时,首先需要将该Jar至于CLASSPATH环境变量中,JVM虚拟机会自动解析CLASSPATH变量中所有的Jar文件,当load一个class文件时,就会从这些CLASSPATH变量中的Jar文件中获取类文件。类加载器会根据一个类的package,将其转换成相应的文件夹层次关系,例如com.wozipa.study.java.access会转换成com/wozipa/study/java/access,从CLASSPATH的根路径下沿着文件夹层次关系进行查找。

(3)冲突

有时我们会使用两个相同类名称的类,在代码编写过程中就会出现类名冲突,就是说使用这个类名时,编译器不知道该类名指向的是哪一个类文件。这种情况下我们需要通过类的全限定名来告知编译器类的具体路径:
例如下面,当我们使用第二个PackageTests时,需要通过指定全限定名称来指出类的位置。

import com.wozipa.study.java.access.PackageTests;

public class DefaultTests 
    public static void main(String[] args)
    
    PackageTests tests = new PackageTests();
    com.wozipa.study.java.nio.PackageTests tests1 = new com.wozipa.study.java.nio.PackageTests();
    

2、Java访问修饰符

Java访问修饰符通过修饰类、属性、方法、构造器等,来控制所修饰的实体的访问权限。Java的访问修饰符一共四个:private、friendly(包默认权限,默认权限),protected和public。

(1)friendly

包访问权限,顾名思义,就是指当一个属性或者方法(包括构造器方法)使用该权限修饰时,这个属性或者方法可以被同一个Package内的其他类直接使用,而其他Package的类将无法直接该属性或者方法。

(2)public

公开访问权限,被public权限修饰符修饰的属性或者方法函数(包括构造器函数)可以被其他任意的客户端程序进行直接访问。

(3)private

私有权限,被private修饰的属性或者方法函数只能在本类(而不是类文件,也就是说类文件中的 其他类也没办法直接访问该类的私有属性或方法)中使用。
例子:当我们对构造函数用private修饰时,其他类就无法通过new方式来创建对象,如果排除反射,这个基本无法被别人初始化,通过这个原理就有了单例模式:

public class Singletom 

    public static Singletom singletom = null;

    public static Singletom getSingletom()
    
        if(singletom == null)
        
            singletom = new Singletom();
        
        return singletom;

    
    private Singletom()

这里的单例模式只是简单的说明实现原理,完整的单例模式需要更负责的代码,后面会总结单例模式的多种实现方式。

(4)protected

继承关系权限,被protected修饰的属性或者方法能够被子类或者同一个Package的类使用。也就是说protected除了继承关系权限外,还具有包访问权限。
注意:子类中定义的protected,父类无法使用。

(5)访问手段

想要访问一个属性或者方法是,只能通过一下手段:
(1)将该属性或者方法定义为public权限,客户端可以直接访问和使用
(2)将属性和方法定义为protected方法,可以被子类或者同一个Package的类使用。
(3)对属性或方法使用默认权限,同一个Package内的其他类能够被使用。
(4)对属性使用私有方法使,使用访问器(getter)和变异器(setter)进行属性的获取和变更

(6)默认包的权限

当一个类在声明时没有通过package关键字添加包定义,那么这个类就会存在默认包中,而从JDK1.4开始,默认包的中的将无法直接被访问和使用,即默认包中的类即使是public修饰,用户依旧没有办法获取该类的访问。如果想使用默认包中的类时,必须使用反射技术去获取该对象的实例:

public class DefaultTests 

    private String name ="default package tests";

    @Override
    public String toString() 
        return name;
    
public static void main(String[] args)

    try 
       Class clazz = Class.forName("DefaultTests");
       System.out.print(clazz.newInstance().toString());
     catch (ClassNotFoundException e) 
            e.printStackTrace();
     catch (IllegalAccessException e) 
            e.printStackTrace();
     catch (InstantiationException e) 
            e.printStackTrace();
    

3、接口与实现

访问控制权限经常被称为具体实现的隐藏。把数据和方法包装到类中,以及具体实现的隐藏,通常共同成为封装。从这句话中,封装不简单的包装,而且还有具体属性和方法的访问控制。这样的原因有两个:
(1)我们通过访问控制来定义客户端程序可以访问和不可访问的权限,客户端程序只能访问特定的接口,而逻辑的具体实现通过不可访问全向封装在内部。防止客户端访问一些逻辑内的函数。
(2)通过访问控制权限,客户端只能访问特定接口,当具体实现发生改变时,并不会对客户端程序的接口访问产生任何影响。
因此我们可以总结为:我们通过权限控制,向客户端程序开放特定接口,然后将内部具体实现通过控制权限封装在内部,这样既可以保证客户端程序不会调用不该调用的接口,还可以在内部实现修改时,不会影响到客户端程序。

4、类的访问权限

我们在前面对访问控制进行讲解时,对象都是属性或者方法,下面介绍一下类的访问权限控制。

(1)类文件

1、一个类文件中,允许一个权限为public的类声明和多个默认权限的类声明。
2、类文件中的public修饰的类声明的名称必须与类文件的名称相同,包括大小写
3、类文件可以只声明多个默认权限的类,并且名字不需要与类文件名称相同。

(2)类的权限

类在声明时,只有public和默认权限这两种,没有protected和private。
当我们在将类定义为默认包权限时,类内部的属性和方法的访问权限也就是默认权限,即使是定义了public,也只能被同一个包中的其他类使用。

三、总结

如果有什么错误的地方请帮我指明出来,共勉!

以上是关于Java 访问控制权限的主要内容,如果未能解决你的问题,请参考以下文章

spring容器与java访问权限的关系!

java 访问控制权限

java web访问权限控制

Java 多态 父类和子类方法的访问控制权限

共享权限和NTFS权限的关系

JAVA中的权限修饰符