自己在回答
http://www.iteye.com/problems/15359的问题得到了奖励,但是自己有时间也做了一下试验,但是结果发现自己的回答是错误的,起码是“
elementData指向了新的内存块”这句话是错误的。当时以为“=”是先引用后创建的呢,自以为这样可以保证创建过程的安全性。但是我做了这样的例子:
public class TestRef
{
public Object A;
public static Object B;
public static void main(String[] args)
{
TestRef test = new TestRef();
System.out.println("---------------------------------------");
test.A = new Persion();
System.out.println(test.A);
System.out.println("---------------------------------------");
test.B = new Persion();
System.out.println(test.B);
}
class Persion
{
private static TestRef test = new TestRef();
static
{
System.out.println("Static block");
System.out.println(test.A);
System.out.println(test.B);
System.out.println("---------------------------------------");
}
{
System.out.println("non static block");
System.out.println(test.A);
System.out.println(test.B);
System.out.println("---------------------------------------");
}
Persion()
{
System.out.println("constructor");
System.out.println(test.A);
System.out.println(test.B);
System.out.println("---------------------------------------");
}
}
得出的结果是这样的
Static block
null
null
---------------------------------------
non static block
null
null
---------------------------------------
constructor
null
null
---------------------------------------
Persion@c17164
---------------------------------------
non static block
null
null
---------------------------------------
constructor
null
null
---------------------------------------
Persion@1fb8ee3
两次创建说明在new过程中 static block , block, 一直到 构造函数,说明都没有引用而是构造函数结束后才引用。
为了证明是不是时间太短的原因,又做了一个例子:
public class TestRef
{
public static Object C;
public static void main(String[] args)
{
TestRef test = new TestRef();
TestRef.C = new TestRef();
System.out.println(test.C);
TestRef.C = Persion.getRef();
System.out.println(test.C);
}
}
class Persion
{
private static TestRef test = new TestRef();
public static TestRef getRef()
{
System.out.println("---------------------------------------");
for(int i=0; i<10; i++)
{
System.out.println(TestRef.C);
for(int j=0; j<100000000; j++)
{
new TestRef();
}
}
System.out.println("---------------------------------------");
return new TestRef();
}
}
这个例子的结果是:
TestRef@61de33
---------------------------------------
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
---------------------------------------
TestRef@8d5190
这应该可以说明在新对象创建完成的时候,“=”才起作用把引用赋给对象,这样就说明在arraylist源代码ensureCapacity方法中:
elementData = Arrays.copyOf(elementData, newCapacity);
在copyOf没有内部如果没有给
elementData赋新值的话,
elementData的引用一直还是老的引用,证明老的
elementData还算是安全的。如果说这样的话,源代码中
Object oldData[] = elementData
存在的意义起码我的有些说法就不成立了。
唉!本以为自己回答了一个很好的问题,但是今天却发现时错误的,有点伤心!不知道怎么能修正过来,觉得自己误人了。但是也有些疑惑,就是
如果“=”是先创建后引用的话,如果创建的时间比较长,如果在多线程的环境下,怎么保证自己的创建不被垃圾回收器回收呢?或许java有自己的保护机制吧。
分享到:
相关推荐
这意味着当你创建一个引用类型的实例时,它会分配在堆内存中,并且变量只包含一个指向这个堆内存地址的引用。 #### 二、引用类型赋值过程解析 当我们对引用类型的变量进行赋值操作时,实际上是将源变量所指向的...
### Java中对象创建、初始化与引用详解 #### 一、Java对象、引用及创建过程 在Java中,对象是程序的基本单位,它包含了属性(成员变量)和行为(方法)。对象是由类创建出来的实例,而类则是一组具有相同属性和...
本教程将详细讲解如何进行QT跨目录编译以及多工程集成,重点在于动态库的创建、引用以及pro文件的编写技巧,确保工程间依赖关系的正确设置。 首先,让我们理解Qt的pro文件。它是Qt项目的核心配置文件,用于指定项目...
它被广泛用于存储文本信息,而关于字符串创建的理解,以及"equals()"方法和"=="运算符的区别,是每个Java开发者都应深入掌握的知识点。 首先,让我们来探讨字符串的创建。在Java中,有多种创建字符串的方式: 1. *...
在Java中,`==`和`equals`是两种不同的比较方法,前者比较引用地址,而后者比较对象的实际内容。 首先,让我们来看看`==`运算符的用法。`==`运算符可以用来比较基本数据类型和引用类型。对于基本数据类型,如`int`...
- **减少临时对象**:返回一个`this`的引用可以避免创建不必要的临时对象,从而提高程序的效率。如果赋值运算符不返回任何东西或者返回一个临时对象,则无法进行链式赋值。 4. **实现细节**: - 当实现赋值...
### 值引用与对象引用 #### 一、引言 在编程中,变量的引用方式分为两大类:值引用(Value Reference)和对象引用(Object Reference)。这两种引用方式决定了程序如何处理数据以及数据的存储方式。理解这些概念...
1. 引用被创建的同时必须被初始化(指针则可以在任何时候被初始化); 2. 不能有 NULL 引用,引用必须与合法的存储单元关联(指针则可以是 NULL); 3. 一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变...
3. **创建引用**: `Student stu` 创建了一个类型为 `Student` 的引用变量 `stu`。 4. **赋值**: `=` 运算符将新创建的对象的内存地址赋值给引用变量 `stu`。 #### 三、对象与引用之间的关系 为了更直观地理解对象...
例如,如果在方法中创建了一个新的`String`对象,这实际上创建了一个新的引用,而不是改变原有引用。但原始引用并不会改变,所以`String`对象的比较通常使用`equals()`方法来判断内容是否相等,而不是使用`==`比较...
创建数据库后,使用ADOX.TableClass对象创建一个新的表,例如: ```csharp ADOX.TableClass tbl = new ADOX.TableClass(); tbl.ParentCatalog = cat; tbl.Name = "MyTable"; ``` 然后,添加一个自动增长的字段,使用...
弱引用同样可以与引用队列一起使用,当弱引用的对象被垃圾回收后,该弱引用会被加入到引用队列中。 示例代码: ```java String str = new String("hello"); WeakReference<String> weakRef = new WeakReference(str...
在Java编程中,对象的创建、初始化和引用是核心概念,尤其对于理解内存管理和程序运行机制至关重要。在Java中,对象是类的实例,而引用则用于指向这些对象。让我们深入探讨这些概念。 首先,创建对象是通过`new`...
虚引用必须与引用队列(ReferenceQueue)配合使用,当对象被垃圾收集后,虚引用会被放入队列,以便进一步处理。 - 示例:`PhantomReference<String> phantomRef = new PhantomReference(new String(...
由于弱引用不会阻止垃圾收集,所以使用弱引用的对象在被创建后会很快变得不可达,除非有其他强引用指向它。这在一定程度上保证了内存的有效利用,避免了不必要的内存占用。 在Android中,软引用和弱引用常用于图片...
本教程将详细讲解如何创建WCF服务并进行调用,特别是不通过传统的“添加服务引用”方式,而是直接通过服务地址进行调用,且请求和响应数据采用JSON格式。 首先,我们需要了解WCF服务的基础架构。WCF服务是基于SOAP...
创建引用时必须立即初始化,并且一旦初始化后就不能改变引用的对象。在创建二叉树时,引用可以用来简化节点间的连接操作: ```cpp void insert(Node*& root, int data) { if (root == nullptr) { root = new Node...
当软引用的对象被垃圾回收后,`softRef`会被加入到`queue`中,从而可以通过`poll()`方法检查软引用是否仍然有效。 #### 四、弱引用 (WeakReference) 弱引用比软引用更弱一些,被弱引用关联的对象只能生存到下一次...
在第一个程序中,s1 先被放到了池中,所以在 s2 被创建的时候,程序找到了具有相同值的 s1,将 s2 引用 s1 所引用的对象。 在第二个程序中,我们使用了 new 操作符,它明白的告诉程序:"我要一个新的!不要旧的!...
- 通过`=`操作符让`veh1`引用指向刚刚创建的`Vehicle`对象。 2. **对象与引用的关系**: - 对象是在堆内存中存储的数据结构,包含了由类定义的属性和方法。 - 引用是一个变量,它保存了一个指向对象的地址。 - ...