最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

簡單易懂Java反射的setAccessible()方法

 更新時(shí)間:2022年07月08日 15:12:38   作者:明月幾時(shí)有666  
本文主要介紹了簡單易懂Java反射的setAccessible()方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言:在使用Field類的對象訪問我自定義的Employee類對象的name域時(shí),拋出異常illegalAccessException。查詢原因?yàn)椋涸谠L問name域時(shí),Java進(jìn)行了訪問檢查,發(fā)現(xiàn)該域是private修飾的,不能直接訪問,因此拋出異常。

概要

本文首先詳細(xì)介紹訪問檢查的概念,然后介紹關(guān)于反射的運(yùn)行時(shí)訪問檢查,并說明可能存在的問題。最后介紹可以通過setAccessible方法屏蔽或者說禁用運(yùn)行時(shí)訪問檢查。讓我們開始把~~

一、 什么是Java的訪問檢查

訪問檢查,就是查看成員屬性、成員方法的使用是否符合訪問權(quán)限(public、protected、default、private)。

有點(diǎn)太理論化了,簡單來說,如果一個(gè)類的成員(屬性或者方法)的訪問權(quán)限是private,那么該成員只能在當(dāng)前類中使用;如果一個(gè)類的成員的訪問權(quán)限是public,那么該成員可以在任意類中使用;如果一個(gè)類的成員的訪問權(quán)限是default,那么該成員只能在同一個(gè)包下面的類中使用;如果一個(gè)類的成員的訪問權(quán)限是protected,那么該成員可以在同一個(gè)包下面的類中和其他包下面的該類的子類中使用。

如果,類的成員的訪問權(quán)限是default,你卻在另一個(gè)包中使用了該成員,當(dāng)編譯時(shí),編譯器會進(jìn)行訪問檢查,發(fā)現(xiàn)成員的使用與給定的訪問權(quán)限不一致,因此會報(bào)錯(cuò)。

舉個(gè)例子,在com.example包下創(chuàng)建People類,有四個(gè)成員變量。在com.example.app包下(它是不同于com.example的包)下,使用People類的四個(gè)成員變量。

package com.example;

package com.example;

public class People {

    private int privateVar = 1;
            int defaultVar = 2;
    protected int protectedVar = 3;
    public int publicVar = 4;
}


package com.example.app;

import com.example.People;
public class TestMain {
    public static void main(String[] args) {
        People p = new People();
        System.out.println(p.privateVar);
        System.out.println(p.defaultVar);
        System.out.println(p.protectedVar);
        System.out.println(p.publicVar);
    }
}

編譯后提示,publicVar的使用符合public的訪問權(quán)限,所以沒有出錯(cuò)。

相信大家都理解了訪問檢查是什么,那么,反射對象的訪問檢查是怎么的呢?

一個(gè)類的成員屬性、成員方法、構(gòu)造函數(shù),在反射中分別被抽象為Field、Method、Counstructor類。

我們可以使用Field訪問對象的成員屬性,成員屬性的訪問權(quán)限,編譯器是不知道的,只有運(yùn)行時(shí)才知道。因此對于反射對象(例如Field)訪問權(quán)限的檢查只能交給虛擬機(jī)。

如果,虛擬機(jī)在運(yùn)行時(shí),發(fā)現(xiàn)成員的使用與給定的訪問權(quán)限不一致,如下代碼

package com.example.app;

import com.example.People;
import java.lang.reflect.Field;
public class TestMain {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        People p = new People();
        Class cl = p.getClass();
        
        // 利用反射訪問private修飾的成員變量 
        Field f = cl.getDeclaredField("privateVar")
        System.out.println(f.get(p));        
    }
}

運(yùn)行時(shí),拋出異常:java.lang.IllegalAccessException

綜上,訪問檢查可以時(shí)編譯器在編譯時(shí)進(jìn)行或者虛擬機(jī)在運(yùn)行時(shí)進(jìn)行(主要是針對反射)

二、 setAccessible() 方法介紹

 setAccessible(boolean flag)方法是AccessibleObject類中的一個(gè)方法,它是Field、 Method、Constructor的公共父類。當(dāng)Field、Method或Constructor (三者都是反射對象)分別用于設(shè)置字段(set(Object obj, Object value))或獲取字段(get(Object obj))、調(diào)用方法(invoke(Object obj, Object... args))或創(chuàng)建和初始化類的新實(shí)例(newInstance(Object... initargs))時(shí),將執(zhí)行運(yùn)行時(shí)訪問檢查。

引用自《Java核心技術(shù) 第十版》

注意:方法名setAccessible很容易讓人產(chǎn)生誤解,給人的感覺是設(shè)置了成員的可訪問性,例如,覺得public修飾的成員是任意類都可以訪問的,所以可訪問標(biāo)志是true;覺得private修飾的成員只有本類可以訪問,所以可訪問標(biāo)志是false。其實(shí)不然,不管是什么訪問權(quán)限,其可訪問標(biāo)志的值都為false。

測試代碼如下:

package com.example.app;

import com.example.People;
import java.lang.reflect.Field;
public class TestMain {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        People p = new People();
        Class cl = p.getClass();
        // 打印輸出所有成員變量的名字及可訪問標(biāo)志
        for (Field f : cl.getDeclaredFields()) {
            System.out.println(f.getName() + ": " + f.isAccessible());
        }
    }
}

輸入結(jié)果:

上面中的API說得很清楚,這個(gè)可訪問標(biāo)志表示是否屏蔽Java語言的訪問檢查,默認(rèn)值是false,(上面已經(jīng)測試)

可以通過setAccessible(true) 修改默認(rèn)值,如此會屏蔽Java語言的(運(yùn)行時(shí))訪問檢查,使得對象的私有成員可以訪問,而不報(bào)錯(cuò)。

package com.example.app;

import com.example.People;

import java.lang.reflect.Field;

public class TestMain {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        People p = new People();
        Class cl = p.getClass();

        for (Field f : cl.getDeclaredFields()) {
            //屏蔽對象的訪問檢查
            f.setAccessible(true);
            // 訪問不符合訪問權(quán)限的成員屬性
            System.out.println(f.getName() + " = " + f.get(p));
        }
    }
}

輸入結(jié)果:

 到此這篇關(guān)于簡單易懂Java反射的setAccessible()方法的文章就介紹到這了,更多相關(guān)Java反射setAccessible()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java控制臺實(shí)現(xiàn)猜拳游戲小游戲

    Java控制臺實(shí)現(xiàn)猜拳游戲小游戲

    這篇文章主要為大家詳細(xì)介紹了Java控制臺實(shí)現(xiàn)猜拳游戲小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Mybatis velocity腳本的使用教程詳解(推薦)

    Mybatis velocity腳本的使用教程詳解(推薦)

    很多朋友不清楚在mybatis可以使用各種腳本語言來定義Mapper文件里面的動態(tài)SQL;目前mybatis支持的腳本語言有XML(默認(rèn)的);Velocity和Freemarker三種。下面通過本文給大家介紹Mybatis velocity腳本的使用,一起看看吧
    2016-11-11
  • Java設(shè)計(jì)模式之備忘錄模式

    Java設(shè)計(jì)模式之備忘錄模式

    這篇文章介紹了Java設(shè)計(jì)模式之備忘錄模式,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • Java排序之冒泡排序的實(shí)現(xiàn)與優(yōu)化

    Java排序之冒泡排序的實(shí)現(xiàn)與優(yōu)化

    冒泡排序是一種簡單的交換排序。之所以叫做冒泡排序,因?yàn)槲覀兛梢园衙總€(gè)元素當(dāng)成一個(gè)小氣泡,根據(jù)氣泡大小,一步一步移動到隊(duì)伍的一端,最后形成一定對的順序。本文將利用Java實(shí)現(xiàn)冒泡排序,并進(jìn)行一定的優(yōu)化,希望對大家有所幫助
    2022-11-11
  • SpringBoot整合消息隊(duì)列RabbitMQ

    SpringBoot整合消息隊(duì)列RabbitMQ

    SpringBoot整合RabbitMQ很容易,但是整合的目的是為了使用,那要使用RabbitMQ就要對其有一定的了解,不然容易整成一團(tuán)漿糊。因?yàn)檎f到底,SpringBoot只是在封裝RabbitMQ的API,讓其更容易使用而已,廢話不多說,讓我們一起整它
    2023-03-03
  • StackTraceElement獲取方法調(diào)用棧信息實(shí)例詳解

    StackTraceElement獲取方法調(diào)用棧信息實(shí)例詳解

    這篇文章主要介紹了StackTraceElement獲取方法調(diào)用棧信息實(shí)例詳解,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • IDEA創(chuàng)建Spring項(xiàng)目無法選擇Java8的問題及解決

    IDEA創(chuàng)建Spring項(xiàng)目無法選擇Java8的問題及解決

    文章描述了在使用Spring創(chuàng)建項(xiàng)目時(shí)遇到的問題,通過將服務(wù)器地址從https://start.spring.io/替換為https://start.aliyun.com/,成功解決了無法選擇Java8的問題
    2025-01-01
  • Java對象轉(zhuǎn)json JsonFormat注解

    Java對象轉(zhuǎn)json JsonFormat注解

    這篇文章主要介紹了Java對象轉(zhuǎn)json JsonFormat注解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • java 實(shí)現(xiàn)發(fā)短信功能---騰訊云短信

    java 實(shí)現(xiàn)發(fā)短信功能---騰訊云短信

    如今發(fā)短信功能已經(jīng)成為互聯(lián)網(wǎng)公司的標(biāo)配,接下來通過本文給大家介紹java 實(shí)現(xiàn)發(fā)短信功能---騰訊云短信 ,需要的朋友可以參考下
    2019-08-08
  • 基于list stream: reduce的使用實(shí)例

    基于list stream: reduce的使用實(shí)例

    這篇文章主要介紹了list stream: reduce的使用實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論

浏阳市| 云霄县| 克东县| 同心县| 池州市| 电白县| 淳化县| 松桃| 屏东县| 云安县| 临沂市| 化德县| 江津市| 临西县| 南康市| 稷山县| 监利县| 西昌市| 吉隆县| 博客| 嘉祥县| 闸北区| 万全县| 沐川县| 仁寿县| 从江县| 盐源县| 田阳县| 连江县| 琼海市| 金川县| 英超| 枣强县| 龙泉市| 图们市| 运城市| 宜兰市| 宁武县| 峨边| 静宁县| 祁连县|