关于Java中的变量及变量的作用域

关于Java中的变量及变量的作用域

0. 变量的概念

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

1. Java的变量类型



2. 注意变量的有效取值范围

系统为不同的变量类型分配不同的空间大小,如double型常量在内存中占8个字节,float的变量占4个字节,byte型占1个字节等。

byte b=129;//编译报错,129超出了byte类型的取值范围
float f=3.5;//编译报错,因为小数常量的默认类型为double型。double型在内存中占8个字节,而Java只为float的变量分配4个字节的空间,显然有问题
float f=3.5f;//编译通过

3. 基本数据类型之间的转换

①.自动类型转换(隐式类型转换)

要实现自动类型转换,需要同时满足两个条件:i.两种类型彼此兼容,ii.目标类型的取值范围要大于源类型。

byte b=3;
int x=b;//程序把b的结果自动转换成int型

②.强制类型转换(显式类型转换)

当两种类型彼此不兼容,或目标类型取值范围小于源类型时,自动转换无法进行,就需要强制类型转换。

byte a;
int b;
a=(byte)b;

将int型的变量b的取值强制转换成byte型,再将该值赋给变量a。此时,变量b本身的数据类型并没有改变。

例:

程序清单:Conversion.java

public class Conversion
{
public static void main(String[] args)
{
byte b;
int i=266;
b=(byte)i;
System.out.println("byte to int is"+" "+b);
}
}

程序输出如下:

byte to int is 10

十进制266→二进制100001010

byte类型取值范围为-128~127,所以只能取到010,省略0,所以输出10

也就是用目标内存块去套取源内存中的数据,能套多少算多少

4. 表达式的数据类型自动提升

下面来看一个错误程序:

程序清单:Test.java

class Test
{
public static void main(String[] args)
{
byte b=5;
b=(b-2);
System.out.println(b);
}
}

这段代码中,5-2的值并未超出byte型取值范围,然而却报错



这是因为在表达式求值时,变量值被自动提升为int型,表达式结果也就成了int型,这时想把它赋给byte型变量就必须强制转换了。

因此就应该改成:

b=(byte)(b-2);

关于类型的自动提升,Java定义了若干适用于表达式的类型提升规则

  • 所有byte型、short型和char型的值奖杯提升为int型
  • 如果一个操作数为long型,计算结果就是long型
  • 如果一个操作数为float型,计算结果就是float型
  • 如果一个操作数为double型,计算结果就是double型

    也就是byte、short、char→int→long→float→double

下面演示一些Java的类型自动提升规则:

程序清单:Promote.java

class Promote
{
public static void main(String[] args)
{
byte b=50;
char c='a';
short s=1024;
int i=50000;
float f=5.67f;
double d=.1234;
double result=(f*b)+(i/c)-(d*s);
System.out.println((f*b)+"+"+(i/c)+"-"+(d*s));
System.out.println("result="+result);
}
}

下面看看代码行的类型提升:

double result=(f*b)+(i/c)-(d*s);

在第一个子表达式f*b中,变量b被提升为float类型,该子表达式的结果也被提升为float类型。接下来,在子表达i/c中,变量c被提升为int类型。该子表达的结果提升为int类型。

然后子表达式d*s中的变量s被提升为double类型,该子表达式的结果提升为double类型。

最后这三个结果值类型分别为float、int、double。float类型加int类型的结果是float类型,然后float类型减去double类型,该表达式的最后结果就是double类型。

变量的作用域

大多数程序设计语言都提供了“变量作用域”(Scope)的概念。在C、C++、Java中,一对大括号中间部分就是一个代码块,代码块决定其中定义的变量的作用域。代码块由若干语句组成,必须用大括号括起来,形成一个复合语句,多个复合语句可以潜逃在另外的一对大括号中形成更复杂的复合语句。

{
int x=0;
{
int y=0;
y=y+1;
}
x=x+1;
}

代码块决定了变量的作用域,作用域决定了变量的“可见性”以及“存在时间”。

例如:

程序清单:TestScope.java

public class TestScope
{
public static void main(String[] args)
{
int x=12;
{
int q=96;//x和q都可用
System.out.println("x is "+x);
System.out.println("q is "+q);
}
q=x;/*错误的行,只有x可用,q超出作用域范围*/
System.out.println("x is "+x);
}
}

q作为在里层的代码块中定义的一个变量,只有在那个代码块中位于这个变量定义之后的语句,才可以使用这个变量,q=x语句已经超过了q的作用域,所以编译无法通过。

在定义变量的语句所属的那层大括号之间,就是这个变量的有效作用范围,但是不能违背变量先定义后使用的原则。

6. 局部变量的初始化

在一个函数或函数里面的代码块中定义的变量称为局部变量,局部变量在函数或代码块被执行时创建,在函数或代码块结束时被摧毁。局部变量在进行取值操作前必须被初始化或进行过赋值操作,否则会出现编译错误。例如:

程序清单:TestVar.java

public class TestVar
{
public static void main(String[] args)
{
int x;//应改为int x=0;
x=x+1;//这个x由于没有初始化,编译报错
System.out.println("x is "+x);
}
}

Java中的变量与变量的作用域的更多相关文章

  1. JAVA中局部变量 和 成员变量有哪些区别

    JAVA中局部变量 和 成员变量有哪些区别 1.定义的位置不一样<重点>***局部变量:在方法的内部成员变量:在方法的外部,直接写在类当中 2.作用范围不一样<重点>***局部 ...

  2. Java 中(静态)变量、(静态)代码块的执行顺序

    Java 中(静态)变量.(静态)代码块的执行顺序 非原创 本文讨论 Java 中(静态)变量.(静态)代码块的执行顺序 首先创建 3 个类 1.Foo 类 public class Foo { pu ...

  3. 在 Java 中不使用多余变量交换两个字符串

    在 Java 中不使用多余变量交换两个字符串 public class Test { public static void main(String[] args) { String a = " ...

  4. 关于java中jdk的环境变量配置

    关于java中jdk的环境变量配置 烦死人,在网上找了很长时间.最终找到了一个方法!现在将其总结帮助后来人. 方法/步骤   1 下载好jdk,并按照提示一步步安装,最后记下jdk所在的安装位置,这里 ...

  5. Java中private、protected和public作用域的异同

    Java中private.protected和public作用域的异同 说明:(1)private的作用范围为当前类,protected的作用范围哦不能超过其他包: (2)区别不同的作用域的不同作用范 ...

  6. 理解Java中的对象,变量和方法

    1.对象的创建和销毁 1.1 对象的创建 这里只介绍创建对象与构造方法的关系 (1).每实例化一个对象就会自动调用一次构造方法,实质上这个过程就是创建对象的过程,准确的说,在Java语言中使用new操 ...

  7. Java基础知识强化10:Java中的中间缓存变量机制

    1.对于自增运算++j与j++,由于加一的执行顺序不同,所以Java中有中间缓存变量来储存其单个表达式的值,而j的自增自减的结果依然保留在原来的变量储存区.因为本体是j的值,而单个表达式的值是中间产生 ...

  8. Java中实例方法,实例变量,静态方法,静态变量,final方法重写的问题,覆盖

    Java中只有非私有的实例方法能被重写,即实现多态,子类可以覆盖父类的方法,但是实例变量不能覆盖,若子类和父类均定义了同样名称的变量,则对于子类来说这是两个不同的变量,要想调用父类的变量必须显示去调用 ...

  9. Java入门以及Java中的常量与变量总结

    JDK与JRE的区别: JDK给开发人员使用(包含开发工具),JRE给客户使用(运行java程序的核心类库),JDK包含JRE关键字的含义: JAVA语言赋予特殊含义,具有专门用途的单词,关键字的单词 ...

  10. Java中final关键字修饰变量、方法、类的含义是什么

    Java中的关键字final修饰变量.方法.类分别表示什么含义? 先看一个简单的介绍 修饰对象 解释说明 备注 类 无子类,不可以被继承,更不可能被重写. final类中的方法默认是final的 方法 ...

随机推荐

  1. 纯CSS3实现自定义涂鸦风格的边框

    今天我们要来分享一款基于纯CSS3的自定义边框应用,看上去它像一个Tooltip控件,因为下边框有一个小三角,就像很多地方的引用文本框一样.另外这款CSS3边框是涂鸦风格的,看起来很有个性.用CSS3 ...

  2. java生成指定范围的随机数

    要生成在[min,max]之间的随机整数, import java.util.Random; public class RandomTest { public static void main(Str ...

  3. android入门——数据存储

    首先是SharedPreferences 用户偏好 package com.example.wkp.aboutdata; import android.content.Intent; import a ...

  4. ora-06502

    执行一个存储过程时报这个错误 ORA-06502: PL/SQL: 数字或值错误 发现是定义的字符串的缓冲区太小,赋给字符串的值又太大 修改varchar2(20)  →   varchar2(200 ...

  5. c++中basic_istream::getline()的返回值何时为真

    今天在看primer,17ch中的IO库再探,做课后练习,要求用ifstream.getline(char*, const unsigned, char)读取一个文件,用循环: while(ifs.g ...

  6. poj2459 Treasure Exploration (闭包+二分)

    这道题是让求派出机器人的最少数量,乍一看以为是简单的求最小路径覆盖,后来发现错了,因为有的点可以走多次,而二分中每个点只能走一次,所以要先用floyd进行传递闭包,然后用二分 #include< ...

  7. jq方法

    DOM属性-获取和设置页面元素的DOM属性 .addClass()..attr()..prop()..hasClass()..html()..removeAttr()..removeClass().. ...

  8. Unhandled Exxception “Unhandled exception type IOException”?

    Unhandled Exxception  “Unhandled exception type IOException”? 在Android studio中,自动遇见这个异常报错,如果eclipse会 ...

  9. High Context とLow Context文化

    社会の様々な文化を分類するのに.Low context culture, High context cultureという分け方がある.ビジネススクールのグローバル・マーケティングの授業などでよく取り上 ...

  10. 游戏中网络数据包和HTTP数据的思考

    快下班了,对于这个沙盒类文字游戏,其实考虑的东西还是很多的,服务器的架构,NPC, NPC API的运算,等等等 现在在思考大数据传输,比如背包数据或者拍卖行的商品展示数据在传输的时候的性能问题 目前 ...