Java的字段与局部变量的区别:1.字段Field变量存在于类中,局部变量local variable存在于方法中;2.两者的生命周期不同。局部变量在方法调用时才在栈中生成,调用结束后被系统自动回收;字段变量在类实例化后于堆中生成,并一直保持到程序结束;3.字段变量可以在用户不初始化而系统自动初始化。基本类型置为0,引用类型置为null;局部变量必须要用户进行初始化;4.字段变量可以被public、private、static、final修饰,而局部变量只可以被final修饰。
此外,堆中只保存引用类型数据的地址。如果需要指向返回的引用类型数据,则需要在栈中用new新开辟地址。具体示例如下:
1 package helloWorld; 2 3 public class Variable { 4 int i; 5 public Variable(int i) 6 { 7 this.i=i; 8 } 9 public Variable(){} 10 11 public void variable() 12 { 13 int n=0; 14 System.out.println(n); 15 } 16 17 public void modify(int a) 18 { 19 a=a+1;//实际上a的值未改变 20 } 21 public void modify(int[] a) 22 { 23 for(int i=0;i<a.length;i++) 24 a[i]=a[i]+1; 25 a=new int[a.length];//新开辟栈中的空间用于存储改变后的a值 26 } 27 28 public void display(int a) 29 { 30 System.out.println(a); 31 } 32 public void display(int[] a) 33 { 34 for(int i=0;i<a.length;i++) 35 System.out.print(a[i]+" "); 36 System.out.println(); 37 } 38 39 public void print() 40 { 41 System.out.println(i); 42 } 43 44 }
1 Variable var=new Variable(); 2 int i1=1; 3 int[] i2=new int[]{1,2,3,4}; 4 var.print(); 5 var.modify(i1); 6 var.display(i1); 7 var.modify(i2); 8 var.display(i2); 9 结果为: 10 0 11 1 12 2 3 4 5
虚函数:在Java的类中,子类可以被转换为父类。所以如果定义了父类的表示方法,子类中也定义了相关的方法函数,那么系统会根据传递的类名来自动选择那个类中的方法。
package helloWorld; public class VirtualMethod { protected String name="Person"; public VirtualMethod(){} public void display() { System.out.println(name+": "+"virtualMethod"); } } class VirtualMethodTemp extends VirtualMethod{ private String name="Students"; public VirtualMethodTemp(){} public void display() { System.out.println(this.name+": "+super.name+": "+"VirtualMethodTemp"); } } class TestVirtualMethod { static void display(VirtualMethod v) { v.display(); } }
1 VirtualMethod vm=new VirtualMethod(); 2 VirtualMethodTemp vmt=new VirtualMethodTemp(); 3 TestVirtualMethod tvm=new TestVirtualMethod(); 4 tvm.display(vm); 5 tvm.display(vmt); 6 显示结果为: 7 Person: virtualMethod 8 Students: Person: VirtualMethodTemp
构造函数与初始化
Java的类中,如果用户没有定义构造函数,那么系统会自动定义一个默认的构造函数,此函数不带参数,也不对字段赋值。但若用户定义了构造函数,那么系统不会定义默认构造函数。
类中的static对象或方法总是在类初始化前执行。因为一个类可以实例出许多对象,但这些对象共用一个static。因此在实例化对象之前会对static进行处理。
1 package helloWorld; 2 3 public class Initialize { 4 private String name; 5 private int age; 6 public Initialize(){System.out.println("Initialize class");} 7 public Initialize(String name,int age) 8 { 9 this.name=name; 10 this.age=age; 11 System.out.println("Initialize class"); 12 } 13 static { 14 System.out.println("Initialize static"); 15 } 16 }
1 Initialize ini=new Initialize(); 2 结果为: 3 Initialize static 4 Initialize class
对于类的继承,子类构造函数在构造前会调用父类的构造函数。如果没有特殊说明,会调用默认的父类构造函数default。因此,用户如果在父类中定义了构造函数,则一定需要包括空构造函数,否则子类的构造函数在编译时无法通过。
此外,在子类的static、父类构造函数、子类构造函数中,执行的优先级依次降低。
1 class IniStudent extends Initialize 2 { 3 public IniStudent()//系统自动加入super(){} 4 { 5 System.out.println("Initialize Student"); 6 } 7 public IniStudent(String name,int age) 8 { 9 super(name,age); 10 System.out.println("Initialize Students"); 11 } 12 static 13 { 14 System.out.println("Initialize Student class"); 15 } 16 }
1 IniStudent inis=new IniStudent(); 2 结果为: 3 Initialize Student class 4 Initialize class 5 Initialize Student
Java中有一种垃圾回收机制,用户可以用包java.lang.AutoClose中的try(){}来回收文件或网络执行完后产生的垃圾内存。其效果相当于resources.closee()。
1 try(Scanner scanner=new Scanner(System.in)) 2 { 3 String str=scanner.nextLine(); 4 try 5 { 6 PrintStream fileOut=new PrintStream("./test.txt"); 7 System.setOut(fileOut); 8 System.out.println(str); 9 }catch(IOException e) 10 { 11 e.printStackTrace(); 12 } 13 } 14 System.setOut(System.out);