有一道java面试题,大概是这样的:
public class Test {
public static void main(String args[]){
String s;
System.out.println("s="+s);
}
}
看起来真的很简单,那么答案是什么呢?编译不通过。
如果在笔试现场有IDE能让你使用,恐怕再简单不过了,答案自动就告诉你了。可惜笔试的时候根本没有电脑,而且更多的程序都要靠自己笔写。
那么回过头来看一下为什么编译不通过呢?其实java里的一切都被视为对象,操纵的标识符实际上是对象的一个“引用”(reference)。怎么来理解这句话呢,在《Thinking in java》中,作者有如下精妙比喻:可以将这一场景想像成用遥控器(引用)来操纵电视机(对象)。String s便是产生了一个遥控器,若给其赋值则绑定到了某个具体的电视机上了。当然,即使没有电视机,遥控器也可以存在,但是当向遥控器发送消息时,若电视机不存在,则会返回错误了。因此,一种更安全的做法是:创建一个引用的同时便进行初始化的操作。
注意:若类的某个成员变量是基本数据类型,即使没有进行初始化,java也会给其一个默认值。那么为什么上面这个程序中的s没有被附上初始值呢?最主要的原因是,只有当变量作为类的成员使用时,java才确保为其附上初始值。在这里,尽管String不是java的基本数据类型,不过若通过类的成员调用时,还是可以被附上null这个初始值。
既然要创建对象,那么程序运行时,对象是怎么进行放置安排的呢?特别是在内存中又是怎样分配的呢?有6个不同的地方可以存储数据:
1、寄存器:(最快,因为它在处理器的内部)
2、堆栈:(位于通用RAM中,随机访问存储器,速度仅次于寄存器)虽然某些java数据存储于堆栈中,特别是对象引用,但是java对象本身并不存储于其中,因为其需要让编译器事先知道存储在堆栈内所有数据的确切大小和生命周期,生成相应代码,以便上下移动堆栈指针来进行分配和释放内存。
3、堆:一种通用的内存池(也位于RAM区),用于存放所有的java对象。使用堆比使用堆栈有更大的灵活性:当需要创建一个对象时,只需用new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。当然为了这种灵活性,付出了相应的代价:花费了比在堆栈中进行存储分配更多的时间。
4、静态存储:“静态”是指“在固定的位置”(尽管也在RAM中)。静态存储里存放的是程序运行时一直存在的数据。用关键字static来表示某个对象的特定元素是静态的,但java对象本身从来不会存放在静态的存储空间里。
5、常量存储
6、非RAM存储
对于5和6,书中虽然有解释,但是自己没有什么特别体会,所以先暂时不写了。
分享到:
相关推荐
在上例中,Son 类没有父类,也没有显示定义构造方法,所以调用默认的无参构造方法来创建对象 S。如果在类 Son 中显示定义了一个或多个带参数的构造方法,创建对象时 Java 编译器会根据创建的对象语句中的参数的个数...
` 在这种情况下,虽然看起来s的内容发生了变化,但实际上创建了一个新的String对象,原始的"abc"对象仍然存在,但不再被引用,会被垃圾回收器回收。 - 字符串拼接:使用+运算符进行字符串拼接时,每次操作都会创建...
### 浅谈内存泄漏:初级分析与实例解析 在软件开发尤其是C/C++编程领域,内存管理是一项核心技能,不当的内存操作往往会导致程序运行不稳定,甚至崩溃。内存泄漏是其中最常见的问题之一,它指的是程序在申请内存后...
总结来说,`s:select`标签在Struts2中用于创建下拉列表,当`list`属性设置为`Map`对象列表时,可以通过`listKey`和`listValue`属性指定`Map`中的键来获取选项的值和文本。这种方法在处理复杂的数据绑定场景时非常...
当创建包装对象时,是通过new关键字使用Number、Boolean和String这三个构造函数来创建的。包装对象虽然看起来和原始值一样,但它们的类型已经变成了 'object'。例如,使用var n = new Number(123)创建了一个数字类型...
- `%s`格式化:`print("My name is %s and age is %d years old" % ('Bob', 30))` - `.format()`方法:`print("My name is {} and age is {} years old".format('Bob', 30))` - Python 3.6的f-string:`a = '...
void print(String s) { // 参数为字符串 // 执行代码 } ``` 重载与函数的返回类型无关,只关注函数名和参数列表。当调用重载方法时,Java会根据传递的实际参数类型来决定调用哪个方法。 总的来说,理解Java中的...
当我们创建一个字符串对象,如`String s = "abc"`,如果常量池中已经存在"abc",那么s将直接指向这个已存在的字符串,而不是创建新的对象。这种方式可以避免重复的字符串对象,节省内存。此外,使用`String.intern()...
此外,还有一些其他的函数,如`is_object()`用于检测变量是否为对象,`is_integer()`, `is_bool()`, `is_float/is_double/is_real()`, `is_null()`, `is_array()`, `is_string()`, `is_resource()`等,它们用于检查...
### 浅谈Python数据类型及类型转换 在Python编程语言中,掌握数据类型及其相互之间的转换至关重要。数据类型是程序设计的基础,理解每种数据类型的特性和用途可以帮助开发者更好地组织和处理数据。本文将深入探讨...
这个方法使用正则表达式`"[\\s+]"`来匹配任意空白字符作为分隔符,然后通过`split()`函数将字符串分割为多个元素,并将它们添加到一个排序后的`TreeSet`实例中。这样可以确保集合中的元素没有重复且按某种顺序(如...