導航:首頁 > 編程語言 > java靜態私有變數

java靜態私有變數

發布時間:2023-01-20 12:27:01

A. 如何理解java靜態內部內私有靜態變數可以被外部訪問,代碼如下:

這個並不算外部,還在這個類的內部,所以可以訪問,你要測試外部應該把這段代碼放到另外一個類裡面測試

B. java類的靜態變數設計public還是private

靜態變數除了被聲明為常量外很少使用,靜態變數是指聲明為public/private,final和static類型的變數。

C. java 中靜態塊里變數為什麼不能私有化

靜態變數是要佔用內存的,在編譯時只要是定義為靜態變數了,系統就會回自動分配內存給他,而答內部類是在宿主類編譯完編譯的,也就是說,必須有宿主類存在後才能有內部類,這也就和編譯時就為靜態變數分配內存產生了沖突,因為系統執行:運行宿主類->靜態變數內存分配->內部類,而此時內部類的靜態變數先於內部類生成,這顯然是不可能的,所以不能定義靜態變數!

D. java 類變數 靜態變數

publicclassDemo
{
privateinta;//實例變數
privatestaticinta;//靜態變數(也叫類變數)
publicvoidfun1(){
//這個是實例方法
}
publicvoidstaticfun2(){
//這個是靜態方法(類方法)
}
}
publicstaticvoidmain(String[]args){
//這里調用實例方法
Demodemo=newDemo();
demo.fun1();

//這里調用靜態方法
Demo.fun2();

}

E. java中static 與private的用法

private是訪問許可權修飾符,用於控制外界對類內部成員的訪問,表明對象成員是完全私有的,不容許外界的任何訪問。
static是靜態成員修飾符,其修飾的靜態變數脫離具體對象獨立存在,在內存中之後一份拷貝,所有的對象都公用這一個存儲空間,所以對static修飾的靜態變數進行的修改對該類的所有對象都起作用。static修飾的靜態函數代表所有對象的統一操作,只能調用靜態變數。static是針對面向對象中的「多態」而提出來的,static修飾的靜態成員不存在多態性。

F. java私有變數

沒有什麼不同的,這兩個程序的區別在於
private int money;
{
money=2000;
}

private int money;
Example4_2()
{
money=2000;
}
這兩個地方。
第一個地方是在定義變數的時候就在域里初始化,第二個地方是在構造函數里初始化,第一個地方等價於private int money=2000;,這兩個程序就是讓你感受一下不同的地方的初始化吧

G. Java反射訪問私有變數和私有方法

引言

對於軟體開發人員來說 單元測試是一項必不可少的工作 它既可以驗證程序的有效性 又可以在程序出現 BUG 的時候 幫助開發人員快速的定位問題所在 但是 在寫單元測試的過程中 開發人員經常要訪問類的一些非公有的成員變數或方法 這給測試工作帶來了很大的困擾 本文總結了訪問類的非公有成員變數或方法的四種途徑 以方便測試人員在需要訪問類非公有成員變數或方法時進行選擇

盡管有很多經驗豐富的程序員認為不應該提倡訪問類的私有成員變數或方法 因為這樣做違反了 Java 語言封裝性的基本規則 然而 在實際測試中被測試的對象千奇百怪 為了有效快速的進行單元測試 有時我們不得不違反一些這樣或那樣的規則 本文只討論如何訪問類的非公有成員變數或方法 至於是否應該在開發測試中這樣做 則留給讀者自己根據實際情況去判斷和選擇

方法一 修改訪問許可權修飾符

先介紹最簡單也是最直接的方法 就是利用 Java 語言自身的特性 達到訪問非公有成員的目的 說白了就是直接將 private 和 protected 關鍵字改為 public 或者直接刪除 我們建議直接刪除 因為在 Java 語言定義中 預設訪問修飾符是包可見的 這樣做之後 我們可以另建一個源碼目錄 —— test 目錄(多數 IDE 支持這么做 如 Eclipse 和 JBuilder) 然後將測試類放到 test 目錄相同包下 從而達到訪問待測類的成員變數和方法的目的 此時 在其它包的代碼依然不能訪問這些變數或方法 在一定程度上保障了程序的封裝性

下面的代碼示例展示了這一方法

清單 原始待測類 A 代碼

public class A { private String name = null; private void calculate() { }}

清單 針對單元測試修改後的待測類 A 的代碼

public class A { String name = null; private void calculate() { }}

這種方法雖然看起來簡單粗暴 但經驗告訴我們這個方法在測試過程中是非常有效的 當然 由於改變了源代碼 雖然只是包可見 也已經破壞了對象的封裝性 對於多數對代碼安全性要求嚴格的系統此方法並不可取

方法二 利用安全管理器

安全性管理器與反射機制相結合 也可以達到我們的目的 Java 運行時依靠一種安全性管理器來檢驗調用代碼對某一特定的訪問而言是否有足夠的許可權 具體來說 安全性管理器是 java lang SecurityManager 類或擴展自該類的一個類 且它在運行時檢查某些應用程序操作的許可權 換句話說 所有的對象訪問在執行自身邏輯之前都必須委派給安全管理器 當訪問受到安全性管理器的控制 應用程序就只能執行那些由相關安全策略特別准許的操作 因此安全管理器一旦啟動可以為代碼提供足夠的保護 默認情況下 安全性管理器是沒有被設置的 除非代碼明確地安裝一個默認的或定製的安全管理器 否則運行時的訪問控制檢查並不起作用 我們可以通過這一點在運行時避開 Java 的訪問控制檢查 達到我們訪問非公有成員變數或方法的目的 為能訪問我們需要的非公有成員 我們還需要使用 Java 反射技術 Java 反射是一種強大的工具 它使我們可以在運行時裝配代碼 而無需在對象之間進行源代碼鏈接 從而使代碼更具靈活性 在編譯時 Java 編譯程序保證了私有成員的私有特性 從而一個類的私有方法和私有成員變數不能被其他類靜態引用 然而 通過 Java 反射機制使得我們可以在運行時查詢以及訪問變數和方法 由於反射是動態的 因此編譯時的檢查就不再起作用了

下面的代碼演示了如何利用安全性管理器與反射機制訪問私有變數

清單 利用反射機制訪問類的成員變數

//獲得指定變數的值

public static Object getValue(Object instance String fieldName)

throws IllegalAccessException NoSuchFieldException {

Field field = getField(instance getClass() fieldName);

// 參數值為true 禁用訪問控制檢查

field setAccessible(true);

return field get(instance);

}

//該方法實現根據變數名獲得該變數的值

public static Field getField(Class thisClass String fieldName)

throws NoSuchFieldException {

if (thisClass == null) {

throw new NoSuchFieldException( Error field ! );

}

}

其中 getField(instance getClass() fieldName) 通過反射機制獲得對象屬性 如果存在安全管理器 方法首先使用 this 和 Member DECLARED 作為參數調用安全管理器的 checkMemberAccess 方法 這里的 this 是 this 類或者成員被確定的父類 如果該類在包中 那麼方法還使用包名作為參數調用安全管理器的 checkPackageAccess 方法 每一次調用都可能導致 SecurityException 當訪問被拒絕時 這兩種調用方式都會產生 securityexception 異常

setAccessible(true) 方法通過指定參數值為 true 來禁用訪問控制檢查 從而使得該變數可以被其他類調用 我們可以在我們所寫的類中 擴展一個普通的基本類 java lang reflect AccessibleObject 類 這個類定義了一種 setAccessible 方法 使我們能夠啟動或關閉對這些類中其中一個類的實例的接入檢測 這種方法的問題在於如果使用了安全性管理器 它將檢測正在關閉接入檢測的代碼是否允許這樣做 如果未經允許 安全性管理器拋出一個例外

除訪問私有變數 我們也可以通過這個方法訪問私有方法

清單 利用反射機制訪問類的成員方法

public static Method getMethod(Object instance String methodName Class[] classTypes)

throws NoSuchMethodException {

Method accessMethod = getMethod(instance getClass() methodName classTypes);

//參數值為true 禁用訪問控制檢查

accessMethod setAccessible(true);

return accessMethod;

}

private static Method getMethod(Class thisClass String methodName Class[] classTypes)

throws NoSuchMethodException {

if (thisClass == null) {

throw new NoSuchMethodException( Error method ! );

} try {

return thisClass getDeclaredMethod(methodName classTypes);

} catch (NoSuchMethodException e) {

return getMethod(thisClass getSuperclass() methodName classTypes);

}

}

獲得私有方法的原理與獲得私有變數的方法相同 當我們得到了函數後 需要對它進行調用 這時我們需要通過 invoke() 方法來執行對該函數的調用 代碼示例如下

//調用含單個參數的方法

public static Object invokeMethod(Object instance String methodName Object arg)

throws NoSuchMethodException

IllegalAccessException InvocationTargetException {

Object[] args = new Object[ ];

args[ ] = arg;

return invokeMethod(instance methodName args);

}

//調用含多個參數的方法

public static Object invokeMethod(Object instance String methodName Object[] args)

throws NoSuchMethodException

IllegalAccessException InvocationTargetException {

Class[] classTypes = null;

if (args != null) {

classTypes = new Class[args length];

for (int i = ; i < args length; i++) {

if (args[i] != null) {

classTypes[i] = args[i] getClass();

}

}

}

return getMethod(instance methodName classTypes) invoke(instance args);

}

利用安全管理器及反射 可以在不修改源碼的基礎上訪問私有成員 為測試帶來了極大的方便 尤其是在編譯期間 該方法可以順利地通過編譯 但同時該方法也有一些缺點 第一個是性能問題 用於欄位和方法接入時反射要遠慢於直接代碼 第二個是許可權問題 有些涉及 Java 安全的程序代碼並沒有修改安全管理器的許可權 此時本方法失效

另一種方法

package test;

import java lang reflect Field;

import model Dept;

public class TypeTest {

public static void main(String args[])

{

Dept d=new Dept();

d setDeptNo( );

d setDName( v );

d setLoc( mopish );

delete(d Dept class);

}

public static void delete(Object obj Class<?> clazz)

{

try

{

System out println( ? +(obj instanceof Dept));

System out println(clazz getName());

System out println(clazz getDeclaredFields() length);

for(Field f: clazz getDeclaredFields())

{

f setAccessible(true);

System out println(f getName());

System out println( +f get(obj));

}

}catch(Exception e)

{

e printStackTrace();

}

}

}

package model;

public class Dept {

private long deptNo;

private String DName;

private String Loc;

public long getDeptNo() {

return deptNo;

}

public void setDeptNo(long deptNo) {

this deptNo = deptNo;

}

public String getDName() {

return DName;

}

public void setDName(String dName) {

DName = dName;

}

public String getLoc() {

return Loc;

}

public void setLoc(String loc) {

Loc = loc;

}

lishixin/Article/program/Java/hx/201311/26190

H. JAVA中靜態變數的問題

靜態變數只能寫在類中而不能寫在方法中,因為靜態變數也稱為類變數,是整個類的所有實例對象都能引用的,而且僅在第一次生成這個類的對象時為這個靜態變數分配空間,故這個靜態變數對於該類的所有實例對象是公用的。對象如果把變數(非靜態變數)寫在類的某個方法中,實例對象中的該變數就是私有的了,對象相互間不能引用及修改該變數。

退一步說,所有寫在方法中的變數都是局部變數,都不能被方法外部調用。

I. java語言中修飾成員變數,聲明私有變數的關鍵字急

static

static關鍵字修飾的成員變數與類變數不是一個概念的東西
static變數,方法稱之為靜態方法,也就是說不用實例化一個對象,他就存在。而且該類的所有實例的static變數都是一樣的,改變其中一個,其他的實力中的static變數都跟著改變
static修飾的成員變數又稱為類變數。不加static修飾的成員變數又叫對象變數。對象變數依附於具體的對象實例,它的值因具體對象實例的不同而不同,而類變數為該類的所有對象共享,它的值不因類的對象不同而不同

J. 在Java中,到底什麼是靜態變數呢

答:在程序開發時,我們經常希望一個變數和方法不隨對象的改變而改變,甚至在沒有創建對象時也能訪問數據和方法,這時就可以在數據和方法上加上Static關鍵字,被Static修飾的數據就叫做靜態變數(數據)而方法就叫靜態方法。靜態變數在內存中的地址是相同的,所以對於同一類的不同對象,它們靜態變數的值肯定是相同的。

閱讀全文

與java靜態私有變數相關的資料

熱點內容
蘋果皮能用流量嗎 瀏覽:548
電腦寬頻連接共享wifi密碼 瀏覽:655
最新微粒貸app官方下載 瀏覽:923
win10電腦怎麼休眠不斷網 瀏覽:530
如何查到網站的伺服器 瀏覽:225
編程怎麼確定一個數的位數 瀏覽:362
如何安裝ae腳本文件夾 瀏覽:914
商品驗偽用什麼APP查 瀏覽:350
請問大數據與會計專業做什麼的 瀏覽:77
如何修改數據上年結轉 瀏覽:6
win7一直配置文件重啟 瀏覽:124
佳能ir2525i網路掃描 瀏覽:283
win10指紋無法識別 瀏覽:646
jsp中怎麼引入js文件 瀏覽:925
文件名構成部分 瀏覽:484
興國互聯網app有哪些 瀏覽:475
北京時間票房多少票房統計數據 瀏覽:750
探探文件夾是哪個 瀏覽:429
如何分類微信文件 瀏覽:446
城市天際線win10 瀏覽:813

友情鏈接