—恢复内容开始—

首先 自己写了个小测试,代码如下

  1. 1 import java.util.ArrayList;
  2. 2
  3. 3 public class QuoteTest {
  4. 4 public static void main(String[] args){
  5. 5 //test String
  6. 6 String str = "value";
  7. 7 TestClass tc = new TestClass();
  8. 8 tc.ChangeVlaue(str);
  9. 9 System.out.println("str now is"+str);
  10. 10 //test int
  11. 11 int num = 0;
  12. 12 tc.ChangeVlaue(num);
  13. 13 System.out.println("num now is"+num);
  14. 14 //test objectclass
  15. 15 TestClass testClass = new TestClass();
  16. 16 System.out.println("testClass now is"+testClass+";num:"+testClass.num);
  17. 17 tc.ChangeVlaue(testClass);
  18. 18 System.out.println("testClass now is"+testClass+";num:"+testClass.num);
  19. 19 //test Arrry
  20. 20 ArrayList<String> liststr = new ArrayList<String>();
  21. 21 liststr.add("str1");
  22. 22 tc.ChangeVlaue(liststr);
  23. 23 System.out.println("liststr now is"+liststr);
  24. 24 }
  25. 25 }
  26. 26
  27. 27 class TestClass{
  28. 28 public TestClass(){
  29. 29 System.out.println("TestClass constructor ");
  30. 30 }
  31. 31 int num = 0;
  32. 32 public void ChangeVlaue(String str){
  33. 33 str = "changed value";
  34. 34 }
  35. 35 public void ChangeVlaue(int num){
  36. 36 num ++;
  37. 37 }
  38. 38 public void ChangeVlaue(TestClass testClass){
  39. 39 testClass.num ++;
  40. 40 testClass = new TestClass();
  41. 41 testClass.num ++;
  42. 42 //hangeVlaue(testClass.num);
  43. 43 }
  44. 44 public void ChangeVlaue(ArrayList<String> liststr) {
  45. 45 liststr.add("str2");
  46. 46 }
  47. 47 }

输出结果如下:

TestClass constructor
str now isvalue
num now is0
TestClass constructor
testClass now isTestClass@2503dbd3;num:0
TestClass constructor
testClass now isTestClass@2503dbd3;num:1
liststr now is[str1, str2]

在调用函数传入值时/会修改参数的内部值属性如属性和集合中的值,但参数的地址不会发生改变,一些简单的类型更不会被修改值,

 

测试时存在一个疑惑:

在代码38行传过来的参数,在给其赋值为什么地址依然是@2503dbd3 没有发生变化,new一个对象的原理是什么? 并先修改39的num时,18行调用时会显示num++; 但若是放在40后面,则不会++,但这两个的地址不是相同的吗?

new 一个对象:

1.javac编译.java源文件形成.class字节码文件; 
2.new SubClass()对象时,先检查有没有父类,有父类,类加载器(ClassLoader)先将父类的Class文件读入内存,创建一个java.lang.Class对象,然后加载子类,类加载器将子类的Class文件读入内存,创建一个java.lang.Class对象; 
3.先初始化父类的静态属性,再初始化父类的静态代码块; 
4.再初始化子类的静态属性,再初始化子类的静态代码; 
5.在堆内存中分配内存空间,分配内存地址,此时是因为父类的特有属性才在堆内存中为父类对象分配空间。 
6.初始化父类的特有属性。 
7.初始化父类的构造代码块。 
8.初始化父类对象相应的构造方法。 
9.在堆内存中分配内存空间,分配内存地址,此时是因为子类的特有属性才在堆内存中为子类对象分配空间的。 
10.初始化子类的特有属性。 
11.初始化子类的构造代码块。 
12.初始化子类相应的构造方法。 
13.将子类的内存地址赋值给栈中的引用对象。 

 

版权声明:本文为imaye原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/imaye/p/9564282.html