JAVA开发之 22-JAVA中的变量

在java中,数据是以常量和变量两种方法形式进行存储和表示的(实际上,所有程序的数据都是这两种形式)。数据处理方法作为程序的另一组成基础,其相关内容将另外单独整理汇总。
常量较之变量,无论是使用频率和使用事项都要少的多。所以,这里以介绍变量为主。
一、Java变量的定义
1、变量的基本声明
声明格式:

type variableName [=value][, variableName[=value]...];

type可以是java的基本类型之一。
java的基本类型,即原生数据类型(Primitive Data Type),详见下面的变量分类的介绍;
type可以是Java的引用类型(即类及接口类型)的名字,外部类或接口必须有访问权限,使用非lang包下的类必须先导入。
变量名(variableName),java约定变量名以能描述该变量意义的单词表示(单词小写),以增加程序的可读性。
value是与指定类型type一致或兼容的变量的初始值,可选。
“=”,表示赋值,不是数学意义上的“等于”,java环境下的“等于”通常用于逻辑表达式,用符号“==”(双等号)表示。赋值同样不等于就相等哟,比如:

Integer a =129,b =129;
System.out.println(a==b);

//结果:false
其中a、b为Integer型引用变量,赋的值都是129,但是两者并不相等。具体原因是因为
同类型变量可以同时声明,中间以“,”(英文逗号)分隔。

2、变量的扩展声明
声明格式:

purview [static] [final] type variableName [=value][, variableName[=value]...];

purview,变量的访问权限修饰符,访问权限标识符比照类的访问权限,具体请参阅《类的定义》;
static,静态成员变量修饰符,与它相对应的是实例变量(没有static修饰)。
final,最终变量修饰符,即常量。

类变量与实例变量的相同点:
1)都可以用任意权限修饰符对访问权限加以限制;
2)都可以被类自身的方法直接调用。

类变量与实例变量的区别是:
1)存储位置不同。静态变量存储于方法区,而实例变量存储于堆区。
2)生命周期不同。静态变量在加载类过程中优先加载,其生命周期取决于类的生命周期;实例变量在创建实例时才创建,它的生命周期取决于实例的生命周期。
3)引用对象不同。静态变量属于类,被类的所有实例共享,可以直接使用类名来引用也可以通过类的实例引用;而实例变量则属于某个对象,它必须在创建对象后才可以通过这个对象来使用。
4)使用方法不同。一个类只能有一个同名静态变量,无论是通过类或者任何一个实例对静态变量重新赋值,结果都是一样;而一个类创建多少个实例就会有多少个同名实例变量,各实例变量存储空间不同,对其中一个实例变量重新赋值不影响其它实例的同名变量。

java虚拟机的体系结构:
方法区,又叫静态区,跟堆一样,被所有的线程共享,它包含所有的class和static变量;方法区中包含的都是在整个程序中永远唯一的元素。
栈(stack)区,分为3部分:基本类型变量区、执行环境上下文、操作指令区。每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。每个线程包含一个栈区,栈中只保存基础数据类型的对象的引用和自定义对象的引用,对象都存放在堆区中。栈区另外存放方法参数和局部变量,用于计算;

堆(heap)区存放对象,即类的实例。每个对象都包含一个与之对应的类的信息。jvm只含一个堆,被所有线程共享。堆中不存放基本类型的对象引用,只存放对象本身。

二、Java变量的分类
//后面对Java变量进行分类时参考的事例

public class Variable {
 public Variable(){}
 public Variable(int constructorVar){//No Initialization but only declare,and final only is permitted.
  System.out.println("constructorVar: "+ constructorVar);
 }
 static{
  int staticBlockVar ;//only final is permitted
  staticBlockVar=2;//Modify the value of the static variable

  classVar=1;
  System.out.println("staticBlockVar's value: "+staticBlockVar);//The variable is define in a static block, and Can't use out the block
 }
 {
  System.out.println("non-quasi-static");
 }

 int instanceVar=1;

 //The default value of 0 is automatically assigned to classVar
 int samenameVar;//instance variable
 static int classVar;

 void changVar(int newValOfMemberVar){//No Initialization but only declare,and final only is permitted.
  int samenameVar=1;//local variable,only final is permitted

  try{
  this.samenameVar=3;//The use of a instance variable of the same name with local variable.
  System.out.println("The samenameVar local variable: "+ samenameVar);
  System.out.println("The samenameVar instance variable: "+this.samenameVar);

  instanceVar=newValOfMemberVar;
  classVar=2;

  int[] a;//do not initialize
  int[] array=new int[2];//Initialized to the default values
  array[1]=2;//To the second element to the assignment

  System.out.println("array[0]:"+ array[0]+ " array[1]:"+ array[1]);
  //System.out.println(a[0]);//error

  }catch(Exception ex){
   ex.toString();
  }
  //System.out.println(staticBlockVar);
 }

 public static void main(String[] args) {
  //静态变量可以直接使用类名引用 
  System.out.println("classVar: "+Variable.classVar);
  //实例变量必须通过对象来使用
  //System.out.println(Variable.member);//error:instanceVar is not a field
  Variable varObject =new Variable();
  System.out.println("varObject's instanceVar: "+varObject.instanceVar);

  //同一类的不同实例,分别为实例变量分配存储空间
  Variable varOb =new Variable();
  varOb.changVar(2);
  System.out.println("varOb's instanceVar: "+varOb.instanceVar);
  System.out.println("varObject's instanceVar: "+varObject.instanceVar);

  //同一类的静态变量,只分配一个存储空间
  System.out.println("classVar: "+Variable.classVar);
  System.out.println("varOb classVar: "+varOb.classVar);
  System.out.println("varObject classVar:" + varObject.classVar);


 }
}

1、根据声明方式详细来区分,Java的变量有八种,下面的程序代码展示了这八种变量的声明方式:
1.1 class variable(类变量):
声明在class内,method之外,且使用static修饰的变量,如上例中的classVar
1.2 instance variable(实例变量):
声明在class内,method之外,且未使用static修饰的变量。如上例中的instanceVar

类变量与实例变量的相同点:
1)两者都可以用任意权限修饰符对访问权限加以限制;
2)两者都可以被类自身的方法直接调用。
3)两者都可以不显式初始化直接使用。
java虚拟机会自动以默认值对它们进行初始化,因此它没有违反java所有的变量必须初始化以后才能使用的约定。

类变量与实例变量的区别是:
1)存储位置不同。静态变量存储于方法区,而实例变量存储于堆区。
2)生命周期不同。静态变量在加载类过程中优先加载,其生命周期取决于类的生命周期;实例变量在创建实例时才创建,它的生命周期取决于实例的生命周期。
3)引用对象不同。静态变量属于类,被类的所有实例共享,可以直接使用类名来引用也可以通过类的实例引用;而实例变量则属于某个对象,它必须在创建对象后才可以通过这个对象来使用。
4)使用方法不同。一个类只能有一个同名静态变量,无论是通过类或者任何一个实例对静态变量重新赋值,结果都是一样;而一个类创建多少个实例就会有多少个同名实例变量,各实例变量存储空间不同,对其中一个实例变量重新赋值不影响其它实例的同名变量。
1.3 formal parameter variable(形参变量)
包括一般方法参数变量(method parameter,声明在method小括号内的变量,如上例中的newValOfMemberVar)和构造器参数变量(constructor parameter,声明在constructor小括号内的变量,如上例中的constructorVar)。java要求形参变量,只能使用默认访问权限和final声明,并且声明
时不能同时初始化。
1.4 local variable(狭义的局部变量):
声明在method内的变量,只能以final修饰。
当方法内的局部变量与成员变量(指类变量或实例变量)同名时,以”this”关键字加以区别。如上例中实例变量sameanmeVar与方法changVar()中定义的局部变量
sameanmeVar同名,实例变量在使用时加前缀“this.”与局部变量加以区别。
1.5 exception-handler parameter(异常标识变量):
声明在catch小括号内的变量,如上例中ex。
异常标识变更即catch方法的形参必须声明为Exception对象及其子对象类型,它只用于紧跟着的执行语句块内。
1.6 array element(数组):
数组的元素值没有识别名称,必须透过数组和索引值(index)来识别,索引值从0开始。如上例中array数组第2个元素的使用。
新建一个数组,如果没有直接赋值,jVM会自动为它所有的元素初始为默认值。注意:是新建一个数组,不是声明一个数组。如上例中数组a[]只声明没有初始,使用会提
示错误。
1.7-1.8 static block variable(静态块变量主)和非静态块(non-quasi-static):
声明在静态块内(static{…})或非静态块内({})的变量。如上例中的变量staticBlockvar。它只能由final修饰,并且仅用于在声明的静态块内。
在使用这两种变量时要注意它们所在块的不同。一是执行时间不同。非静态变量是执行构造方法之前;静态块在类文件加载后的初始化阶段执行 。二是执行次数不同。静态块只在类加载初始过程中执行一次;每一次初始化对象,都会导致一次非静态块的执行。这部分详细信息请参阅欣’s博客-《Java中自由块的执行顺序》。
2、根据变量内存来分类,Java变量有两种:
2.1 heap variable:占用的内存在heap中,这类变量包括了class variable,instance variable,array component,这类变量会自动被JVM初始化默认值。
2.2 stack variable:通常广义的局部变量(pan-local variable),其占的内存在stack中,这类变量包括了狭义的局部变量,method parameter,exception-handler
parameter,constructor parameter。狭义的局部变量不会被JVM初始化成默认值,使用者必须自行初始化该变量,但是parameter类(包括method parameter,exception-handler parameter,constructor parameter)会被JVM初始化成传入值(即实参)。
3、根据使用方式来为变量分类,主要有三种:
3.1 class variable,与根据声明分类对应。
3.2 instance variable,与根据声明分类对应。
3.3 广义的局部变量,除了上面两种以及数组元素以外,都可视为广义的局部变量,数组通常被视为对象,array component视为对象的instance variable.

参考资料:《JAVA变量的种类》.蔡学镛.,《Java中自由块的执行顺序》-http://blog.163.com/yaxctgu@126/blog/static/1626703182011872344170/

三、Java变量使用注意事项:
1、在Java中,所有的变量必须先声明再使用。
2、在static 方法中引用任何实例变量都是非法的。这里就不举例了,你可以试着在上例中添加代码测试一下。

public  class Test {
 static int bc=3;
 int de;
 static{
  int ab =1;//final型
  System.out.println("variable of static block ab: " + ab);
  System.out.println("class static member variable bc: " +bc);
 }

 static class StaClass{
  public StaClass(){System.out.println("static class");}
     public void chgVar(){
      //ab=2;//静态块内的代码只在加载时执行一次,其中的变量可以认为是常量,是final的,不可修改。
     }
 }
 public static void main(String[] args){
  //Test t = new Test();
  StaClass staclass= new StaClass();

 }
}

一般来说,静态方法常常为应用程序中的其它类提供一些实用工具所用,在Java的类库中大量的静态方法正是出于此目的而定义的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值