Java 在堆的PermGen区域中是否有所有基本类型的池?
我知道堆的PermGen区域中字符串池的概念。所以当我们做类似的事情时Java 在堆的PermGen区域中是否有所有基本类型的池?,java,heap,permgen,Java,Heap,Permgen,我知道堆的PermGen区域中字符串池的概念。所以当我们做类似的事情时 String firstString = "Stack"; String secondString = "Stack"; 引用firstString和secondString都指向池中的同一对象。但是我对int类型的变量尝试了同样的方法 int firstInt = 5; int secondInt = 5; if(firstInt == secondInt) { System.o
String firstString = "Stack";
String secondString = "Stack";
引用firstString
和secondString
都指向池中的同一对象。但是我对int类型的变量尝试了同样的方法
int firstInt = 5;
int secondInt = 5;
if(firstInt == secondInt) {
System.out.println("Both point to same allocated memory");
} else {
System.out.println("Both point to different allocated memory");
}
结果是都指向同一个对象
Integer firstInteger = new Integer(2);
Integer secondInteger = new Integer(2);
if(firstInteger == secondInteger) {
System.out.println("Both point to same object");
} else {
System.out.println("Both point to different object");
}
输出均指向不同的对象
我对char尝试了同样的方法,结果是相似的。那么我的问题是,我们是否有所有基本类型的池,比如
int
,char
?当我们实际使用new()
创建具有相同内容的对象时,就像上面提到的第二种情况一样,对象是被克隆并存储在同一个池区域还是在池外部?原语不是对象。它们可以直接存储在生成的代码中
在第二个代码块中,您测试的是值相等,而不是两个对象相同
int firstInt = 5;
int secondInt = 5;
if(firstInt == secondInt)
{
System.out.println("Both point to same object");
// NO - neither point to an object -- their alues are the same.
}
通过显式使用
Integer.valueOf(int)
,您可以在多个引用之间共享同一个整数对象,这可能会在多次调用时返回同一个对象。您的帖子中有很多误解,甚至很难开始解释。买一些像样的书。目前,一些事实可能会对您有所帮助:
- 字符串不是基元类型
- 没有基元类型池,因为不能引用基元类型(回答说它们只保留在堆栈上是完全错误的!)
- 如果您使用
,您仍然会绕过池;因此执行new
将始终创建一个新的String对象;您不能更改newstring(“ala”)
的语义李>new
- 如果要使用可用的池,请在对象上使用工厂方法(如
),它们在某种程度上将池实例(将Integer.valueOf
,整数
等的所有可能值汇集在一起是不可行的,也不有益的)浮点
if (Integer.valueOf(2) ==Integer.valueOf(2))
您将获得true
使用Integer firstInt=newinteger(2)
可以创建一个新的局部变量=
到另一个使用Integer secondInt=new Integer(2)
创建的局部变量。字符串
类型也是如此
这背后的原因是=
检查变量的相等性。变量可能不同(=
结果为false
),即使它们指向两个“相同”的对象。此上下文中的相同表示obj1。equals(obj2)
返回true
如果您想在PermGen中存储primitve类型和字符串的对象表示,则不要使用
new
关键字,即Integer firstInt=2代码>,stringfirststring=“whatevs”
bea因为关键字new
有时会在堆上创建一个对象,为了回答高级问题,只需查看源代码即可。例如,下面是Integer#valueOf(int i)
方法的代码:
int firstInt = 5;
int secondInt = 5;
if(firstInt == secondInt) {
System.out.println("Both point to same allocated memory");
} else {
System.out.println("Both point to different allocated memory");
}
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
公共静态整数值(int i){
如果(i>=IntegerCache.low&&i我相信这是一个需要回答的非常有效的问题。对于未来的读者来说,==操作对对象类型和基元类型的工作方式是不同的
基本类型(int、char、double、long…)通过其值进行计算。
而基本包装(整数、双精度、字符串…)实际上是对象,而不仅仅是值
所以当我们使用Integer类作为
整数=新整数(10)
在内存中创建一个新对象,这与基本数据类型不同
==求值检查内存,以及对象类型和基元类型的值,只检查值。在第一个使用int
的示例中,您根本不处理对象,而是处理基元,因此它不适用。+1,另请参见,我没有提到字符串是基元类型的任何地方!我的q问题是我们有类似的基本类型池吗?@AniketThakur-为什么需要基本类型池?以我问题中提到的第一种情况为例。它如何将两个点打印到同一个对象?我的观点是,它必须注意确保firstInt和secondInt分配相同的内存。@AniketThakur-请参阅我的答案这个问题-它们具有相同的值,而不是相同的内存。如果不重写obj1.equals(obj2)仅内部调用==运算符。我的问题与第一个问题一样,JVM如何确保两个int变量具有相同的内存分配?这些多个引用存储在何处?如何确保它们都指向相同的int变量(考虑到它是实例变量,它在堆上)?对于基元局部变量,值直接存储在方法生成的字节码中,局部变量存储在堆栈上。两者都没有引用。对于Integer.valueOf(),共享对象由Integer类存储在专用缓存中。