黑马程序员:类变量、成员变量实例变量局部变量静态变量全局变量

---------------------- android培训java培训、期待与您交流! -----------------------


突然感觉学java跟取经一样,得经历九九八十一难,随着学习的深入,解除了众多变量,当时学习的时候看的明明白白的,但现在暮然回首,傻了,好吧,今天总结一下,希望以后不会忘记:

类体由2部分构成:
  
  一部分是变量的定义;
  一部分是方法的定义(一个类中可以有多个方法)
  
  在变量定义部分定义的变量叫做类的成员变量,成员变量在整个类中都有效.
  
  (全局变量应该是成员变量的俗称)
  
  在方法体中定义的变量叫做局部变量,局部变量只在定义它的方法中有效.
  
  成员变量又分为
  实例变量
  和
  类变量(static静态变量).
  
  class One
  {
  float x; //x为实例变量
  static int y; //只要有关键字static, y为类变量
  }
  
  局部变量是在函数或方法中的变量,实例变量指的是类的一个实例,就是一个对象, 成员变量就是类中的变量(不是方法中的变量!), 类变量是类中的静态变量。
  
  
    局部、实例、成员变量的作用域和生存周期同局部变量一样,而类变量如果用public声明则作用域同全局变量,如果是private则作用域只在类的内部,
  
  生存周期同全局变量.
  
  成员方法和类方法跟局部变量和类变量的关系一样.
  
  
  1.栈 - 由编译器自动分配释放
  2.堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
  3.全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束释放
  4.另外还有一个专门放常量的地方。- 程序结束释放
  
  java类的成员变量有俩种:
  
  一种是被static关键字修饰的变量,叫类变量或者静态变量;
  另一种没有static修饰,为实例变量。
  
  类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期。
  
  而实例变量取决于类的实例。每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期。
  
  public class Temp {
  int t; //实例变量
  public static void main(String args[]){
  int t=1; //局部变量
  System.out.println(t); //打印局部变量
  Temp a= new Temp(); //创建实例
  System.out.println(a.t); //通过实例访问实例变量
  }
  }
  
  结果为:
  1
  0 (成员变量具有缺省值 而局部变量则没有)
  
  把代码改为
  
  public class Temp {
  static int t; //类变量
  public static void main(String args[]){
  System.out.println(t); //打印类变量
  int t=1; //局部变量
  System.out.println(t); //打印局部变量
  Temp a= new Temp(); //创建实例
  System.out.println(a.t); //通过实例访问实例变量
  }
  }
  
  结果则为
  0
  1
  0
  
  关于一个protected的例子 发现了一个容易被忽视的错误
  
  一般来说 访问控制分4种级别:
  
  公开:public 同类 同包 子类 不同包 都可以访问
  默认:只向同包同类放开
  私有:private 只有类本身可以访问
  保护:protected 向子类以及同一个包中的类放开
  
  来看一下在该节中的例子
  先定义一个ClassA 并把它放在mypack1包中
  
  package mypack1;
  public class ClassA {
  public int var1;
  protected int var2;
  int var3;
  private int var4;
  
  public void method(){
  var1=1;
  var2=1;
  var3=1;
  var4=1;
  
  ClassA a = new ClassA();
  a.var1=1;
  a.var2=1;
  a.var3=1;
  a.var4=1;
  }
  }
  
  然后又在另外一个包 mypackage2中 存在ClassA的一个子类 ClassC
  
  package mypack2;
  import mypack1.ClassA;
  class ClassC extends mypack1.ClassA{
  public void method(){
  ClassA a = new ClassA();
  a.var1=1;
  a.var2=1; //此行出错
  }
  }
  
  实际上这个例子有问题
  你会看到ide(或者编译时)在 a.var2=1 这一行报错 提示不能访问protected对象
  这就是protected经常被人忽视的地方
  尽管ClassC是ClassA的一个子类
  但是在ClassC中创建的是ClassA的一个实例
  该实例中的protected成员变量则很明显没有被ClassC继承到
  自然在ClassC中无法访问var2
  
  所以对于这种情况 将代码改为如下,则可以编译通过。
  
  package mypack2;
  import mypack1.ClassA;
  class ClassC extends mypack1.ClassA{
  
  public void method(){
  ClassA a = new ClassA();
  a.var1=1;
  super.var2=1;
  ClassC c = new ClassC();
  c.var1=1;
  c.var2=1;
  }
  }
  
  OK,用java in a nutshell中的一段话来总结一下全文:
  
  protected access requires a little more elaboration. Suppose class A declares a protected field x and is extended by a class B, which is defined in a different package (this last point is important). Class B inherits the protected field x, and its code can access that field in the current instance of B or in any other instances of B that the code can refer to. This does not mean, however, that the code of class B can start reading the protected fields of arbitrary instances of A! If an object is an instance of A but is not an instance of B, its fields are obviously not inherited by B, and the code of class B cannot read them.
  
  静态变量:
  也称为类变量!在程序加载时系统就为它在堆中开辟了内存,堆中的内存地址存放于栈以便于高速访问。静态变量的生命周期--一直持续到整个"系统"关闭。 (待考量)
  
  实例变量:
  当你使用java关键字new的时候,系统在堆中开辟并不一定是连续的空间分配给变量(比如说类实例),然后根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的"物理位置"。 实例变量的生命周期--当实例变量的引用丢失后,将被GC(垃圾回收器)列入可回收“名单”中,但并不是马上就释放堆中内存。
  
  局部变量:
  局部变量,由声明在某方法,或某代码段里(比如for循环),执行到它的时候直接在栈中开辟内存并使用的。当局部变量脱离作用域,存放该作用域的栈指针,栈顶与栈底重合即为释放内存,速度是非常快的。
  
  
  ava优化编程-静态变量
  
  静态变量
  
  在程序运行期间,类中的静态变量其内存空间对所有该类的实例是共享的,因此在某些时候,为了节省内存空间开销,共享资源,
  我们可以将类中的变量声明为静态变量。
  但是因为静态变量生命周期太长,并且不易被系统回收,所有如果使用不合理,就会适得其反,从而造成大量内存的浪费。
  因此建议在全部符合下列条件的情况下才使用静态变量:
  (1)变量所包含的对象体积较大,占用内存较多
  (2)变量所包含的对象生命周期较长
  (3)变量所包含的对象数据稳定
  (4)该类的实例 有 对该变量包含对象的共享需求
  
  关键字: java 变量 作用域
  1. 类的静态变量在内存中只有一个。静态变量位于方法区,被类的所有实例共享。静态变量的生命周期取决于类的生命周期(即类何时被加载和卸载)。
  
  2. 类的每个实例都有相应的实例变量。实例变量位于堆区中。实例变量的生命周期取决于实例的生命周期(即实例何时被创建及销毁)。
  
  3. 假如成员变量(包括静态变量和实例变量)是引用变量,那么当该成员变量结束生命周期时,并不意味着它所引用的对象也一定结束生命周期。变量的生命周期
  和对象的生命周期是两个不同的概念。
  
  4. 局部变量位于栈区,其生命周期取决于所属的方法何时被调用及结束调用。
  
   总结一下:
   局部变量位于栈区,静态变量位于方法区,实例变量位于堆区,方法的字节码位于方法区,对象本身位于堆区,对象的引用位于栈区。





--------------------- android培训java培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net/heima

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值