# 所有局部变量都是放在栈内存中,引用类型变量所引用的对象总是存储在堆内存中
# 不允许直接访问堆内存中的数据
# 类体内定义的变量称为成员变量,若无static则是非静态变量或实例变量,若使用了static,则为静态变量或类变量
# 类变量初始化时机总是处于实例变量初始化之前,一个JVM内的一个类变量只需一快内存空间
# 类也是对象,所有类都是Class的实例,获取Class实例,可通过Person.class 或 Class.forName("Person")
# 程序可以在3个地方对地方实例变量执行初始化
Ⅰ 定义实例变量时指定初始值
Ⅱ 非静态初始化块中对实例变量指定初始值
Ⅲ 构造器中对实例变量指定初始值
~ 1、2比3更早执行,1、2执行的顺序与他们在源程序排列顺序相同
# 定义类变量时指定初始值和静态初始化块中对类变量指定初始值 这两种方式执行顺序与源程序中排列顺序相同。
# 当创建任何java对象时,程序总会先一次调用每个父类非静态初始化块、父类构造器(从Object开始)执行初始化,最后才调用本类的非静态初始化块、构造器执行初始化
# 子类构造器执行中即没有super调用,也没有this调用,系统将会执行子类构造器之前,隐式调用父类无参数构造器
# super和this调用都必须作为构造器第一行代码,且最多只能调用其中之一,且最多调用一次
# super关键字本身没有引用任何对象,子类方法不能直接使用return super,但可使用return this;不允许把super当成变量使用
# 方法参数传递机制:值传递——将实际参数值的副本传入方法内,参数本身不会受影响,如果传递的是的对象,则传递对象的引用值
父子实例的内存控制
继承成员变量和继承方法区别:方法的行为总是表现出它们实际类型的行为;实例变量的值总是表现出声明这些变量所用类型的行为
1 class BaseConsole:2
2 {
3 int count = 2;
4 public void display()
5 {
6 System.out.println(this.count);
7 }
8 }
9 class Derived extends Base
10 {
11 int count = 20;
12 @Override
13 public void display()
14 {
15 System.out.println(this.count);
16 }
17 }
18 public class FieldAndMethodTest
19 {
20 public static void main(String[] args)
21 {
22
23 Derived d = new Derived();
24
25 Base bd = new Derived();
26 System.out.println(bd.count);
27 bd.display();
28
29 Base d2b = d;
30 System.out.println(d2b.count);
31 d2b.display();
32 }
33 }
20
2
20
1 class BaseConsole:200
2 {
3 int count = 2;
4 }
5 class Mid extends Base
6 {
7 int count = 20;
8 }
9 public class Sub extends Mid
10 {
11 int count = 200;
12 public static void main(String[] args)
13 {
14 //创建一个Sub对象
15 Sub s = new Sub();
16 //将Sub对象向上转型后赋为Mid、Base类型的变量
17 Mid s2m = s;
18 Base s2b = s;
19 //分别通过3个变量来访问count实例变量
20 System.out.println(s.count);
21 System.out.println(s2m.count);
22 System.out.println(s2b.count);
23 }
24 }
20
2
# 可通过super.count访问父类定义的count实例变量
# 系统内存中并不存在Mid和Base两个对象,只有一个Sub对象,其保存了所有父类定义的全部实例变量
class Fruit
{
String color = "未确定颜色";
//定义一个方法,该方法返回调用该方法的实例
public Fruit getThis()
{
return this;
}
public void info()
{
System.out.println("Fruit方法");
}
}
public class Apple extends Fruit
{
//重写父类的方法
@Override
public void info()
{
System.out.println("Apple方法");
}
//通过super调用父类的Info()方法
public void AccessSuperInfo()
{
super.info();
}
//尝试返回super关键字代表的内容
public Fruit getSuper()
{
return super.getThis();
}
String color = "红色";
public static void main(String[] args)
{
//创建一个Apple对象
Apple a = new Apple();
//调用getSuper()方法获取Apple对象关联的super引用
Fruit f = a.getSuper();
//判断a和f的关系
System.out.println("a和f所引用的对象是否相同:" + (a == f));
System.out.println("访问a所引用对象的color实例变量:" + a.color);
System.out.println("访问f所引用对象的color实例变量:" + f.color);
//分别通过a、f两个变量来调用info方法
a.info();
f.info();
//调用AccessSuperInfo来调用父类的info()方法
a.AccessSuperInfo();
}
}
Console:
a和f所引用的对象是否相同:true
访问a所引用对象的color实例变量:红色
访问f所引用对象的color实例变量:未确定颜色
Apple方法
Apple方法
Fruit方法
# 可以把this当成普通变量的返回值
public class ReturnThis { public int age; public ReturnThis grow() { age++; //return this,返回调用该方法的对象 return this; } public static void main(String[] args) { ReturnThis rt = new ReturnThis(); //可以连续调用同一个方法 rt.grow() .grow() .grow(); System.out.println("rt的age属性值是:" + rt.age); } }
# 个数可变的形成只能处于形参列表的最后,一个方法最多只能有一个长度可变的形参
1 public class Varargs 2 { 3 //定义了形参个数可变的方法 4 public static void test(int a , String... books) 5 { 6 //books被当成数组处理 7 for (String tmp : books) 8 { 9 System.out.println(tmp); 10 } 11 //输出整数变量a的值 12 System.out.println(a); 13 } 14 15 16 17 public static void main(String[] args) 18 { 19 //调用test方法,为args参数可以传入多个的字符串 20 test(5 , "Struts2权威指南" , "基于J2EE的Ajax宝典"); 21 //调用test方法,为args参数可以传入多个的字符串 22 test(23 , new String[]{"Ruby On Rails敏捷开发最佳实践" , "轻量级企业应用实战"}); 23 24 } 25 }