导航:首页 > 编程语言 > 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静态私有变量相关的资料

热点内容
可以用微信传送的文件app 浏览:294
pdf文件解析乱码 浏览:479
光照无关图代码 浏览:688
Linux读写文件前八位 浏览:597
word如何绘制饼状图 浏览:172
w7系统搜索文件夹 浏览:618
java线程变量 浏览:854
苹果电脑word是只读文件 浏览:691
ps5国行备份文件大小 浏览:754
linux恢复删除文件命令 浏览:805
win10家庭版打不开qq文件 浏览:794
女生来例假有哪个app比较好 浏览:66
调用后台接口为什么不显示数据 浏览:363
js判断重复 浏览:422
联通如何切换到网络电视 浏览:191
学编程的优势哪里靠谱 浏览:939
沟通文件 浏览:267
水准测量平差程序 浏览:78
cf如何解决网络误封 浏览:952
折叠式文件夹是什么意思 浏览:796

友情链接