发表于: java/j2ee | 作者: | 日期: 2009/12/09 02:12

java变量概述

在程序运行期间,系统为程序分配一块内存单元,用来存储各种类型的数据。系统分配的内存单元要使用一个标记符来标识,这种内存单元中的数据是可以更改的,所以叫做变量。定义变量的标识符就是变量名,内存单元中所装载的数据就是变量值。用一个变量定义一块内存以后,程序就可以用变量名代表这块内存中的数据。

变量是由一个标识符、类型及一个可选初始值的组合定义。此外,所有的变量都有一个作用域,定义变量的可见性,生存期。

==========================

java变量声明及初始化

在Java 中,所有的变量必须先声明再使用。基本的变量声明方法如下:


type identifier [ = value][,identifier [= value] …] ;

type 是Java 的基本类型之一,或及接口类型的名字。

标识符(identifier )是变量的名字,指定一个等号和一个值来初始化变量。

请记住初始化表达式必须产生与指定的变量类型一样(或兼容)的变量。声明指定类型的多个变量时,使用逗号将各变量分开。

以下是几个各种变量声明的例子。注意有一些包括了初始化。


int a, b, c; // declares three ints, a, b, and c.

int d = 3, e, f = 5; // declares three more ints, initializing // d and f.

byte z = 22; // initializes z.

double pi = 3.14159; // declares an approximation of pi.

char x = ‘x’; // the variable x has the value ‘x’.

java变量的命名规则
1、由字母、数字组成,另外还可以使用两个特殊符号:”_”和”$”。
2、不能使用数字开头。
3、变量名区分大小写,例如 a 和 A是两个不同的变量。
4、”_”和”$”一般为代码生成器使用,人工写出来的代码不鼓励使用”_”和”$”。
5、java的字符集是unicode,所以可以使用中文的类名及变量名。

动态初始化
尽管前面的例子仅将字面量作为其初始值,Java 也允许在变量声明时使用任何有效的表达式来动态地初始化变量。

例如,下面的短程序在给定直角三角形两个直角边长度的情况下,求其斜边长度。


// Demonstrate dynamic initialization.
class DynInit {
public static void main(String args[]) {
double a = 3.0, b = 4.0;

// c is dynamically initialized

double c = Math.sqrt(a * a + b * b);

System.out.println(“Hypotenuse is ” + c);
}
}

这里,定义了3个局部变量a,b,c。前两个变量a和b初始化为常量。然而直角三角形的斜边c被动态地初始化(使用勾股定理)。该程序用了Java 另外一个内置的方法sqrt(),它是Math类的一个成员,计算它的参数的平方根。这里关键的一点是初始化表达式可以使用任何有效的元素,包括方法调用、其他变量或字面量。

==========================

java变量的分类

根据声明方式来为变量分类

根据声明方式详细来区分,Java的变量有七种,下面的程序代码展示了这七种变量的声明方式:


Class Myclass {
static int a;
int b;
public static void myMethod(int c) {
try {
int d;
} catch(Exception e) {
}
}
MyClass(int f) {
int[]g = new int[100];
}
}

class variable:声明在class内,method之外,且使用static修饰的变量,例如上面程序代码的a.

instance variable:声明在class内,method之外,且未使用static修饰的变量,例如上面程序的b.

method parameter:声明在method小括号内的变量,例如上面程序代码的c.

狭义的局部变量(local variable):声明在method内的变量,例如上面程序代码的d和g.

exception-handler parameter:声明在catch小括号内的变量,例如上面程序代码的e.

constructor parameter:声明在constructor小括号内的变量,例如上面程序代码的f.

数组元素(array element):数组的元素值没有识别名称,必须透过数组和索引值(index)来识别.例如上面程序代码的g[0].

根据变量内存来分类

根据变量内存位置来区分,Java的变量有两种,包括了:

heap variable:
占用的内存在heap中,这类变量包括了class variable,instance variable,array component,即前面程序的a,b,g[0].这类变量会自动被JVM初始化默认值.

stack variable:
通称广义的局部变量(pan-local variable),其占用的内存在stack中,这类变量包括了狭义的局部变量、method parameter、exception-handler parameter、construcor parameter,即前面程序的c、d、e、f。狭义的局部变量不会被JVM初始化成默认值,使用者必须自行初始化该变量,但是parameter类(包括method parameter、ex-ception-handler parameter、constructor parameter)会被JVM初始化成传入值。

根据使用方式来为变量分类

根据使用方式,只要分三类即可,分别是:

class variable:即上例的a.

instance variable:即上例的b.

广义的局部变量:包含上例的c,d,e,f.这四者的差别很小,直接归为一类.

至于”数组元素”(array component)则不在此三类中,但是”数组元素”并不常被注意到,为它多分出一类的用处不大.我通常将数组视为对象,将array component视为对象的instance variable.

本部分摘自《Java夜未眠》P187《变量的种类》
==========================

变量的作用域和生存期

在java中代码块决定了变量的作用域。代码块指一堆花括号之间的部分,它由若干语句组成,用大括号括起来之后形成了一条复合语句,多个复合语句可以嵌套在另外的一个大括号中形成更复杂的复合语句。

一个代码块定义了一个作用域(scope )。这样,每次开始一个新块,就创建了一个新的作用域。

作用域可以进行嵌套。例如每次当你创建一个程序块,你就创建了一个新的嵌套的作用域。这样,外面的作用域包含内部的作用域。这意味着外部作用域定义的对象对于内部作用域中的程序是可见的。但是,反过来就是错误的。内部作用域定义的对象对于外部是不可见的。

为理解嵌套作用域的效果,考虑下面的程序:


// Demonstrate block scope.
class Scope {
public static void main(String args[]) {
int x; // known to all code within main

x = 10;
if(x == 10) { // start new scope
int y = 20; // known only to this block

// x and y both known here.
System.out.println(“x and y: ” + x + ” ” + y);
x = y * 2;

}
// y = 100; // Error! y not known here

// x is still known here.
System.out.println(“x is ” + x);
}
}

正如注释中说明的那样,在方法main() 的开始定义了变量x,因此它对于main() 中的所有的随后的代码都是可见的。在if程序块中定义了变量y。因为一个块定义一个作用域,y 仅仅对在它的块以内的其他代码可见。这就是在它的块之外的程序行y=100; 被注释掉的原因。如果你将该行前面的注释符号去掉,编译程序时就会出现错误,因为变量y在它的程序块之外是不可见的。在if程序块中可以使用变量x,因为块(即一个嵌套作用域)中的程序可以访问被其包围作用域中定义的变量。

变量可以在程序块内的任何地方被声明,但是只有在他们被声明以后才是合法有效的。因此,如果你在一个方法的开始定义了一个变量,那么它对于在该方法以内的所有程序都是可用的。反之,如果你在一个程序块的末尾声明了一个变量,它就没有任何用处,因为没有程序会访问它。例如,下面这个程序段就是无效的,因为变量count 在它被定义以前是不能被使用的。


// This fragment is wrong!
count = 100; // oops! cannot use count before it is declared!
int count;

另一个需要记住的重要之处是:变量在其作用域内被创建,离开其作用域时被撤消。

这意味着一个变量一旦离开它的作用域,将不再保存它的值了。因此,在一个方法内定义的变量在几次调用该方法之间将不再保存它们的值。同样,在块内定义的变量在离开该块时也将丢弃它的值。因此,一个变量的生存期就被限定在它的作用域中。

如果一个声明定义包括一个初始化,那么每次进入声明它的程序块时,该变量都要被重新初始化。例如,考虑这个程序:


// Demonstrate lifetime of a variable.
class LifeTime {
public static void main(String args[]) {
int x;

for(x = 0; x < 3; x++) { int y = -1; // y is initialized each time block is enteredSystem.out.println("y is: " + y); // this always prints -1y = 100;System.out.println("y is now: " + y); } } }

该程序运行的输出如下:


y is: -1
y is now: 100
y is: -1
y is now: 100
y is: -1
y is now: 100

可以看到,每次进入内部的for循环,y都要被重新初始化为-1。即使它随后被赋值为100,该值还是被丢弃了。

最后一点:尽管程序块能被嵌套,你不能将内部作用域声明的变量与其外部作用域声明的变量重名。在这一点上,Java 不同于C和C++。下面的例子企图为两个独立的变量起同样的名字。在Java 中,这是不合法的。但在C/C++ 中,它将是合法的,而且2个变量bar将是独立的。


// This program will not compile
class ScopeErr {

public static void main(String args[]) {
int bar = 1;
{ // creates a new scope

int bar = 2; // Compile-time error – bar already defined!
}
}
}

==========================

整理自网络

: https://blog.darkmi.com/2009/12/09/1001.html

本文相关评论 - 1条评论都没有呢
Post a comment now » 本文目前不可评论

No comments yet.

Sorry, the comment form is closed at this time.