public class Test { private String s = null; public void get(Test tt) { tt = new Test(); tt.s = "helloooooo"; //s是Test的私有变量,在这里可以被访问到吗???? } public String toString() { return s; } }
首先说明这种使用方法貌似找不到具体应用场景。单看上面的这种用法其实在内存中产生了两个对象 一个是this, 另一个就是在get中创建的tt其实如果你把tt = new Test();想象成局部内部类,只不过没有这样来写吧。 tt = new Test(){};那tt在Test类里面去访问s就自然了。因为tt也属于Test类型了。不知道VM内部是怎么样来实现的,还请高手指点。
如果想访问,你可以为类中的属性添加set/get方法来进行访问。
其实就是一个很不规范的代码编写而已
这要在公司里这么写,马上项目经理就该找你谈话了按照javabean的规范,所有的内部变量都应该通过get/set函数进行访问
public class Test {
private String s = null; public void get(Test tt) {
//调试的结果, 当new 了后 tt 也是null , 这个我也觉得奇怪, null 里面而且还有属性 s
tt = new Test();
tt.s = "helloooooo"; //s是Test的私有变量,在这里可以被访问到吗????
} public String toString() {
return s;
}
}
tt.s当然能打得到 为null而已
其他类,隐藏,不能访问
一句话,本类中可以访问私有变量,对于其他类不可见。
说实在的 以前还真没意识到过,一直以为private变量,是对象内的访问,才知道是类内的访问
在本类定义方法将本类或共子类的对象作为参数传入,是设计上的错误!实际应用中不会出现这种情况!
能访问到,是因为你是在本类调用的。就好比在本类可以使用this调用私有属性!那样也是允许的!
//调试的结果, 当new 了后 tt 也是null , 这个我也觉得奇怪, null 里面而且还有属性 s
tt = new Test();
tt.s = "helloooooo"; //s是Test的私有变量,在这里可以被访问到吗????
}get方法内部new出来的 tt,tt引用tt本身的对象s当然没问题了!!
private String s ;//定义变量
//set/get方法赋值
public void setS (String s){
this.s=s;//引用
} public String getS (){
return s ;//返回
} }
确实,get方法就是用来返回本类成员我一开始看了下,也觉得是不可以。
class Test {
private String s = "123"; public void get(Test tt) {
//调试的结果, 当new 了后 tt 也是null , 这个我也觉得奇怪, null 里面而且还有属性 s
tt = new Test();
// tt.s = "helloooooo"; //s是Test的私有变量,在这里可以被访问到吗????
System.out.println(tt.s);
} public String toString() {
return s;
}
}
public class A{
public static void main(String args[]){
Test t1=new Test();
Test t2=new Test();
t1.get(t2);
}
}这个时候输出的123 你应该懂了吧。tt.s的s还是本类的s,并不是对象tt的s
你可不能说是没有意义哦~~~ 私有变量按你说的必须通过setter,getter来访问,现在这个情况违反了 就值得研究了
protected-受保护的 只有本类或子类或父类中可以访问
public-表示全局 类内部外部子类都可以访问
"这个时候输出的123 你应该懂了吧。tt.s的s还是本类的s,并不是对象tt的s"
照哥们您这种写法 这个s不可能是不是123的 我验证的结果恰恰相反 这个s应该是对象tt的
鉴定完毕。
不要管方法体内new出来的那个Test对象,tt是从外面传进来的对象,为什么本对象可以访问它的成员?
1.本地的同名对象已经覆盖了传进来的参数,参数相当于在本函数内被丢弃了
2.在Test类的方法里,可以访问任何私有成员,就算你没有覆盖传进来的参数,直接使用传进来的参数,也是一样的结果,这是java访问控制的规则决定的,没有为什么,只有遵守。如果你还是无法理解,那么放弃学习java吧, 你只会食古不化,越学越糊涂,不适合做这个。
tt = new Test(){};那tt在Test类里面去访问s就自然了。因为tt也属于Test类型了。不知道VM内部是怎么样来实现的,还请高手指点。
我现在问你两个问题,你就明白了。(1)tt.s算不算是Test类的私有字段。(我可以回答你,必须算)(2)你写的get()方法,是不是在Test类内?(我可以回答你,必须在)那么私有字段在本类中可以访问,没毛病。你可以尝试去理解。并不用死记硬背。
不要误导初学者。tt就是对象引用.new Test().产生了一个Test类的对象实例哪来的局部内部类。
定义为private的成员,指的是,当前类能直接访问,你
public void get(Test tt) {
tt = new Test();
tt.s = "helloooooo";
}
tt.s的tt代表Test的对象实例,而且现在的tt是在Test内部,也是当前类的范围,tt是某个Test的实例本身的指向,和this的含义是一样的,在都是Test的直接访问饮用,所以可以访问,不过,你的tt=new Test()是改变了tt的地址,所以外部的传入去的tt的s是没有被改变。特别protected比较不好理解
在C++里,private的成员,代指的是,本类内的直接指针访问,
protected是代指,本类成员和子类成员的直接指针访问,所以说java的protected是说法是同一个包或子类访问也是错误的说法。protected举例子
class A
{
protected int i;
}class B extends A//B要和A不同包
{
A a=new A();
B b=new B();
public void method()
{ super.i//访问正确 super代表B实例(用于访问父类方式的引用,如果没有被覆盖,和this同等),是A的子类,是A的直接实例指针
this.i//访问正确 this代表B的实例,是A的子类并且是直接指针
a.i//无法访问,明显,B是A的子类,却无法访问,因为a不是B的直接指针(引用)
b.i//访问正确,b是A的子类,并且是子类的直接指针
}
}
我觉得这样理解是正确的,估计很多人写了很久的程序,也学了很多关于“面向对象编程”的概念。却很少去思考面向对象是个什么层次的概念。是编译期还是运行期?
private 是一个编译指示符,是告诉编译器必须检查这个变量或方法是否在只在类引用,这不同于对于数组访问越界的检查。
编译完成以后,tt.s该是哪个对象还是哪个对象,与什么私有不私有没关系。
在内存中tt=new Test(),产生了一个对象,与传入的参数无关。
而tt.s则是从该对象的某个地址引用了一个变量,如一个新对象包含10个string成员变量,每个字符串指针为32位(4字节)那么对象就是40字节大小,如果tt.s是位于tt的第3个变量,那么就是第9~12共4个字节表示的字符串地址(指针)。
被编译后,tt指向new Test()返回的地址(这个地址在编译期不确定,但是new Test()过程会在tt变量地址中写入对象的首地址),而tt.s则指向对象首地址+8。
为什么要用private, 仅仅是要求检查程序逻辑而已,让我们编写的程序逻辑更加严谨,与运行时没有关系。
这也是为什么能用反射机制来查询到一个对象内的所有成员,一个对象的存储结构是一定的,因此只要知道这个结构和首地址,就可以知道每个成员变量的值,而不管其编译前是private还是public,编译后全都只是一个地址而已。
private针对的是其他类的object,这些object是无法访问的