java中内存的分配问题

经常做练习时会遇到空指针的问题,有时候可以明白,有时候不能明白,所以想请教一下前辈们,java中基本数据和引用数据,创建时再内存中是如何分配的,例如,Whyy和Whyy=... 经常做练习时会遇到空指针的问题,有时候可以明白,有时候不能明白,所以想请教一下前辈们,java中基本数据和引用数据,创建时再内存中是如何分配的,例如,Why y和Why y=new Why和Why y=null有什么区别,变量的作用域以{}为准,那么在Test类中,创建一个类对象,调用该类属性的初始化方法,初识化的信息(当中创建的变量)在该对象调用另外一个方法时受不受作用域的限制?可以被另外一个方法使用吗?
例如一个Why类中首先创建了一个集合类对象stuMap(Map stuMap;),又创建了初始化方法 init(),该方法中初始化了该集合类对象stuMap。在该类中的另外一个方法load()中,又直接使用了stuMap来调用Map类的方法,这个时候stuMap指向的是哪一个呢?为什么没有创建具体的对象就可以调用类的方法了呢?在另外一个喊main方法的类中,如果先创建一个Why类对象y,然后y.init();然后 y.load那么load中的stuMap又指向哪里呢?在init中初识化的信息,对load中的stuMap有用吗?

另创建了一个类
public class Stu {
public String name;//Person p;下面可以直接输出p
public Stu(){}
public void ru()
{
System.out.println(name);
}
}
又创建了
public class test {
public static void main(String[] args) {
String name=null;
Stu stu=new Stu();//如果只是定义Stu stu;为什么下面无法输出stu?
int a=0;
System.out.println(name+"\t"+a+"\t"+stu.name);
stu.ru();
}
}
为什么在main方法中,必须为属性赋值或创建对象才能打印输出,而在前一个类的方法中可以直接打印输出呢?
展开
 我来答
百度网友d320c32
2012-04-13 · 超过19用户采纳过TA的回答
知道答主
回答量:35
采纳率:0%
帮助的人:38.1万
展开全部
根据楼主的描述,感觉楼主的思想还停留在面向过程的层面上,对于java这样的纯面向对象的语言的语法和调用机制感到迷茫。这是很正常的,面向对象和面向过程本来就是两个东西,从面向过程转到面向对象,确实有点困难。
在你的问题中,你说“为什么在main方法中,必须为属性赋值或创建对象才能打印输出,而在前一个类的方法中可以直接打印输出呢?”,这个问题证明了你对java中“类”和对象的概念没有理解清楚,首先,name属性石类Stu的成员变量,权限为public,因此任何类Stu的实例都可以通过.来引用该成员,但是其他类无法绕过Stu及其对象而引用该属性(其实应该这么说,面向对象的语言中,没有面向过程的语言中所谓的‘全局变量’,定义一个变量,该变量必须属于某个类的,在java中也肯定是属于某个类的,而不能是如你所想的那样,某个类中定义一个变量,任何类都可以绕过其所在类直接使用变量名来引用该变量,这是不可能实现的)。
举个例子来讲,你(类Stu)可以使用自己的手(变量name),来做任何事(System.out.println(name)),因为对于你来说手是你自己的,因此可以自由使用,这是宪法(JVM)赋予你(任何类)的自由权利但是对于其他人(类test)来说,如果要使用你的手(System.out.println(name+"\t"+a+"\t"+stu.name)),必须通过你(Stu.name),才能使用,难道你见过别人请你帮忙的时候,只带走了你的手,而没有把你带走吗?
关于虚拟机在执行Why y = new Why();代码时,是如何分配内存的,一楼已经回答的很清楚了,我就不再赘述了。
最后,建议楼主多看看java入门,好好理解面向对象的思想,这一点无论是刚入门,还是日后你成为技术大牛,做架构设计,这一点都是至关重要的,至少在java世界中是这样的。
更多追问追答
追问
谢谢,感觉很形象,慢慢消化中,那补充问题的第一个问题呢?
也不完全是没有理解类和对象,或者这样说,如果把Why中的String name,换成另外一个自定义类例如Person p,那么在Why类中的ru方法中,不是也可以直接用System.out.println(p);吗?在Why类中,并没有创建Person p=new Person呀,但是在Test中如果只是定义Stu stu;,想要直接用System.out.println(stu);就不行,这是为什么呢?
追答
import java.util.HashMap;
import java.util.Map;

/**
*
* @author 杨胜寒
*/
public class Why {

//声明一个Map对象,此范例中所有使用的map引用都是这个map
public Map subMap;

public void init(){
//实例化subMap,虚拟机首先会在对内存创建一个HashMap对象,然后将其引用赋给subMap
subMap=new HashMap();
//初始化之后,可以初始化一些测试数据
subMap.put("test", "This is a simple question !");
}

public void load(){
//如果没有init方法为subMap初始化,此时subMap将会是一个null,那么下面这行代码将会抛出异常
System.out.println(subMap.get("test"));
}

/**
* 返回subMap对象的引用
* @return
*/
public Map getSubMap() {
return subMap;
}

/**
* 入口函数
* @param s
*/
public static void main(String[] s) {
Why why=new Why();
//如果省略改行代码,subMap的引用将为null,那么下一行代码将会抛出空指针异常
why.init();
//测试从subMap中读取数据
why.load();
//获取why的成员变量subMap的引用
Map map=why.getSubMap();
//此时map的引用于why的成员subMap其实是一样的,将打印出true
System.out.println(map == why.subMap);
//这一行的代码输出的内容将于调用why.load()一致
System.out.println(map.get("test"));
}
}
上例是根据你的描述写的一个范例,该范例中所有Map引用都来自subMap的引用,即subMap与main方法中的局部变量map在内存中其实是一块内存
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式