Java基础教程(5)--变量
一.变量
1.变量的定义
正如上一篇教程《Java基础教程(4)--面向对象概念》中介绍的那样,对象将它的状态存在域中。但是你可能仍然有一些疑问,例如:命名一个域的规则和惯例是什么?除了int还有其他的类型吗?域在声明的时候必须初始化吗?如果域没有显示地初始化会被赋予一个默认值吗?在本文中我们将一一讨论这些问题,但是在开始之前,需要对几个概念进行介绍。在Java中,“域”和“变量”术语都会使用,对于初学者来说这可能有一点困惑,因为它们看起来好像说的是同一个东西。
Java语言定义了以下几种类型的变量:
- 实例变量(非静态域):从技术层面来说,对象将它们各自的状态存在“非静态域”中,也就是没有使用static关键字修饰的域。非静态域也被称为实例变量,因为对于类的每个实例(换句话说,就是每个对象)来说,它们的值都是独立的。例如,每个自行车的当前速度相对于其他自行车来说都是独立的。
- 类变量(静态域):类变量是使用static关键字修饰的域。这告诉编译器无论这个类有多少个实例,这个变量只有一个副本。对于一种特定的自行车来说,它的齿轮数可以被标记为static,因为这个值适用于它的每一个实例。代码static int numGears = 6;将会创建一个静态域。此外,可以使用关键字final来修饰这个域来保证它的值不会改变。
- 局部变量:类似于对象在域中存储其状态,方法通常会将其临时状态存储在局部变量中。声明局部变量的语法与声明域类似(例如,int count = 0;)。没有特殊的关键字将变量标记为局部变量,这完全取决于声明变量的位置——它位于方法的两个大括号之间。因此,局部变量只对声明它们的方法可见,对于类的其他部分来说它们是不可见的。
- 参数:你已经在HelloWorld的main方法和Bicycle类中看到过参数的应用。回想一下main方法的签名——public static void main(String[] args)。这里,args变量是方法的参数。需要记住的是参数属于“变量”而不是“域”。这也适用于其他接受参数的结构(例如构造函数和异常处理),我们将陆续在后面的教程中见到它们。
在理解了这几个概念后,相信你对变量和域的关系有了进一步的认识。变量分为实例变量、类变量、局部变量和参数,而只有实例变量和类变量属于域的概念。你也可能偶尔也会看到“成员”一词,类的域,方法和嵌套类型统称为其成员。
2.命名
变量名是标识符的一种,它满足标识符的规则。标识符用来给程序中需要自定义名称的某个实体命名,例如变量、方法、类、参数等。所有的标识符都需要满足以下的规则或惯例:
- 标识符必须是由字母、数字、下划线(_)、美元符号($)等Java允许作为标识符中一部分的字符组成。可以使用Character.isJavaIdentifierPart()来检测一个字符是否被允许作为Java标识符的一部分。
- 标识符不能以数字或其他不允许作为出现在标识符起始位置的字符开头。可以使用Character.isJavaIdentifierStart()来检测一个字符是否被允许作为Java标识符的第一个字符。
- 标识符不能是关键字、null、true或false。
- 标识符不限制长度。
- 标识符应该尽可能地表达出它的作用或意义以提高程序的可读性。建议使用驼峰法(第一个单词首字母小写,其余单词首字母大写)来为设计标识符。如果是常量(使用final修饰的变量),那么规则稍有变化,将每个字母大写并用下划线(_)分隔每个单词。
上面提到了关键字。关键字是编程语言中事先定义的,有特别意义的单词。下面是Java中的关键字:
其中,const和goto关键字虽然已经不再使用,但是它们还是被保留了下来。true、false和null虽然被很多人误认为是关键字,但实际上它们只是字面量而已。
二.基本数据类型
1.八种基本数据类型
Java是一门静态语言,这意味着所有的变量在使用前必须先进行声明。考虑以下代码:
int gear = 6;
上面的代码声明了一个名为gear的变量,它是整数类型,并且有一个初始值1。变量的类型决定了它所能存储的数据的类型。除int之外,Java编程语言还支持其他七种基本数据类型。Java中的八种原始数据类型是:
- byte:byte数据类型是8位有符号整数。它的最小值为-128(-27),最大值为127(27-1)。
- short:short数据类型是16位有符号整数。它的最小值为-32768(-215),最大值为32767(215-1)。
- int:int数据类型是32位有符号整数。它的最小值为-231,最大值为231-1。
- long:long数据类型是64位有符号整数。它的最小值为-263,最大值为263-1。
- float:float数据类型是单精度32位IEEE754浮点数(如果对浮点数的概念不了解,可以简单地将它理解为小数)。它的有效位数为6~7位,不要使用它去存储对精度要求较高的数据。
- double:double数据类型是双精度64位IEEE754浮点数。它的有效位数为15位。在保存浮点数时,绝大部分情况下都应该使用double类型。
- boolean:boolean数据类型只有两个可能的值:true和false。它一般用来表示条件的真或假。在Java中,boolean数据类型不能与其他数据类型进行相互转换。
- char:char数据类型是单个16位Unicode字符。它的最小值为'\u0000',最大值为'\uffff'。
char类型扩展
要想弄清楚char类型,就必须了解Unicode编码机制。Unicode打破了传统字符编码机制的限制。在Unicode出现之前,已经有许多不同的标准:美国的ASCII、西欧语言中的ISO8859-1、俄罗斯的KOI-8、我国的GB2312等。这样就产生了下面两个问题:一是对于任意给定的编码值,在不同的编码方案下有可能对应不同的字母;二是采用大字符集的语言其编码长度可能不同。例如,有些常用的字符采用单字节编码,而另一些字符则需要两个或更多字节。
设计Unicode编码的目的就是要解决这些问题。在20世纪80年代开始启动设计工作时,人们认为两个字节的代码宽度足以对世界上各种语言的所有字符进行编码,并有足够的空间留给未来扩展。在1991年发布了Unicode 1.0,当时仅占用65536个代码值中不到一半的部分。在设计Java时决定采用16位的字符集,这样会比使用8位字符集的程序设计语言有很大的改进。
十分遗憾,经过一段时间,不可避免的事情发生了。由于增加了大量的汉语、日语和韩语中的文字,Unicode字符超过了65536个,16位的char类型已经不能满足描述所有Unicode字符的需要了。
从JavaSE 5.0开始,码点(code point)是指与一个编码表中的某个字符对应的代码值。在Unicode标准中,码点采用十六进制书写,并加上前缀U+,例如U+0041就是拉丁字母A的码点。Unicode的码点可以分成17个平面。第一个代码级别称为基本多语言平面,码点从U+0000到U+FFFF;其余的16个平面码点从U+10000到U+10FFFF,其中包括一些辅助字符(supplementary character)。
下面来介绍UTF-16。UTF-16是Unicode码的一种编码格式。也就是说,Unicode决定了每个字符所对应的编码的值,而UTF-16是Unicode编码的一种书写格式,与其类似的还有UTF-8和UTF-32。虽然这些格式的表现形式不尽相同,但他们表示的编码是一致的,那就是Unicode编码。UTF-16采用不同长度的编码表示所有Unicode码点。在Unicode中,特定长度的比特序列称为代码单元。例如,UTF-8的一个代码单元的长度为8。UTF-16中16位表示一个代码单元。UTF-16编码的规则如下:
- U+0000到U+D7FF以及U+E000到U+FFFF(基本多语言平面)
这个区间称为基本多语言平面,包含了最常见的字符。每个字符对应的码点使用一个代码单元就可以表示。 - U+D800到U+DFFF(代理区)
因为除基本多语言平面外,其他16个平面的码点无法用2个字节表示,所以Unicode标准规定,基本多语言平面内的U+D800到U+DFFF的码点不对应于任何字符,称为代理区。因此,UTF-16利用保留下来的0xD800-0xDFFF区段的码位来对辅助平面的字符的码位进行编码。 - U+10000到U+10FFFF(辅助平面)
辅助平面中的码点都大于U+FFFF,无法用16位来表示,因此采用一对连续的代码单元来进行编码。具体步骤如下:
a.码点减去0x10000,得到的结果范围在0x00000到0xFFFFF,使用二进制表示为yyyy yyyy yyxx xxxx xxxx;
b.高10位的值(范围为0x000到0x3FF),加上0xD800,得到的结果范围在0xD800到0xDBFF,称为高位代理,作为第一个代码单元;
c.低10位的值(范围也是0x000到0x3FF),加上0xDC00,得到的结果范围在0xDC00到0xDFFF,称为地位代理,作为第二个代码单元;
d.最终的UTF-16编码用二进制表示就是:1101 10yy yyyy yyyy 1101 11xx xxxx xxxx。
在Java中,char类型描述了UTF-16编码中的一个代码单元。建议不要在程序中使用char类型,除非确实需要处理UTF-16代码单元。
2.默认值
在声明一个域时,如果不对它赋值,编译器将赋予它一个默认值。下面是这8种基本数据类型的默认值:
局部变量则略有不同,编译器永远不会为未初始化的局部变量分配默认值。如果没有初始化局部变量,请保证在使用它之前为其赋值。访问未初始化的局部变量将导致编译时错误。
3.字面量
你可能已经注意到在初始化基本数据类型的变量时不使用new关键字。基本数据类型是语言中内置的特殊数据类型,它们不是从类创建的对象。字面量(literal)是用于表达源代码中一个固定值的表示方法。如下所示,可以将字面量分配给基本数据类型的变量:
boolean result = true;
char capitalC = 'C';
byte b = 100;
short s = 10000;
int i = 100000;
(1)整型字面量
整型字面量默认为int类型。可以在整数后面加上后缀L或l来表示long类型字面量。可以使用前缀0x来表示十六进制,0来表示八进制,0b来表示二进制:
// The number 26, in decimal
int decVal = 26;
// The number 26, in hexadecimal
int hexVal = 0x1a;
// The number 26, in octal
int octVal = 032;
// The number 26, in binary
int binVal = 0b11010;
(2)浮点型字面量
浮点型字面量默认为double类型(也可以加上D或d,不过一般省略)。可以在浮点数后面加上后缀F或f来表示float类型字面量。
可以使用科学计数法来表示浮点数字面量。例如,1.2345*104可以表示为1.2345E4,1.2345*10-4可以表示为1.2345E-4。E后面的数字表示10的指数,也可以使用小写字母e。也可以使用十六进制表示浮点数。例如,3.875=(11.111)2=(3.e)16=(3e)16*2-4,那么3.875可以表示成0x3.ep0或0x3ep-4(因为e和十六进制的15重复,所以这里使用p表示指数)。注意,尾数采用十六进制,指数采用十进制。指数的基数是2,而不是10。
(3)字符型字面量
char类型的字面量值要用单引号括起来。例如,'B'是编码值为66所对应的字符常量。它与"B"不同,"B"是一个包含字符B的字符串。char类型的值可以表示为十六进制值,但需要加上前缀\u,其范围从\u0000~\uFFFF。例如,\u03C0表示圆周率符号π。
除了转义序列\u外,还有一些用于表示特殊字符的转义序列,如下表:
所有这些转义序列都可以出现在字符字面量或字符串中。例如'\u2018'或"Hello\n"。转义序列\u还可以出现在字符字面量或字符串之外,而其他转义序列就不可以。例如
public static void main(String\u005B\u005D args)
就完全符合语法,\u005B和\u005D是[和]的编码。但要注意的是,转义序列\u会在编译代码前得到处理。例如,"\u0022+\u0022"并不是一个由双引号包围加号组成的字符串。实际上,\u0022会在编译代码之前替换为",这个字符串会变成""+"",也就是一个空串。更隐蔽的,一定要注意注释中的\u,注释
// Unicode \u000A is a new line
会产生一个语法错误,因为\u000A会被替换成换行符,也就是说,上面的注释会变成下面这样:
// Unicode
is a new line
类似地,下面的注释也会产生语法错误:
// Look inside c:\users
因为\u后面并没有跟着一个十六进制数。
(4)在数字字面量中使用下划线
在JavaSE7及之后的版本中,任意个数的下划线(_)可以出现在数字字面量中的任意两个数字之间。这个功能可以提高数字字面量的可读性,类似于使用逗号或空格等标点符号将每三个数字分为一组的形式。
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;
Java基础教程(5)--变量的更多相关文章
- Java基础教程(12)--深入理解类
一.方法的返回值 当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...
- Java基础教程(25)--I/O
一.I/O流 I/O流表示输入源或输出目标.流可以表示许多不同类型的源和目标,例如磁盘文件.设备.其他程序等. 流支持许多不同类型的数据,包括字节.原始数据类型.字符和对象等.有些流只传递数据 ...
- Java基础教程(18)--继承
一.继承的概念 继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...
- Java基础教程:注解
Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...
- Java基础教程:泛型基础
Java基础教程:泛型基础 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚 ...
- Java基础教程:多线程基础(1)——基础操作
Java:多线程基础(1) 实现多线程的两种方式 1.继承Thread类 public class myThread extends Thread { /** * 继承Thread类,重写RUN方法. ...
- Java基础教程:反射基础
Java基础教程:反射基础 引入反射 反射是什么 能够动态分析类能力的程序称为反射. 反射是一种很强大且复杂的机制. Class类 在程序运行期间,Java运行时系统始终为所有对象维护一个被称为运行时 ...
- Java基础教程:面向对象编程[2]
Java基础教程:面向对象编程[2] 内容大纲 访问修饰符 四种访问修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default ...
- Java基础教程:面向对象编程[1]
Java基础教程:面向对象编程 内容大纲 Java语言概述 Java语言特点 1.Java为纯面向对象的语言,它能够直接反映现实生活中的对象.总之,Everything is object! 2.平台 ...
随机推荐
- Linux mint 安装踩坑记录
记得之前电脑上的那个Ubuntu是去年寒假的时候安装的,算下来自己用Linux也快一年了.虽然在去年暑假的时候我也曾经想过要把Ubuntu升级到18.04可是当时安装了几次都没有成功,自己也就放弃了. ...
- 如何外部访问你的本地网站natapp
用natapp,要实名制才可以获得免得authtoken 1.注册登录: https://natapp.cn/tunnel/lists 2.这个要填写一下,端口我写的是3000 3.客户端下载 解压: ...
- javascript简要笔记
零. 数据 0. 变量 分为字符串,数字,undefined, null,对象 undefined类型是只声明了变量,但是没赋值 可以使用typeof()函数来查看变量类型 例子1 var ...
- SpringBoot idea maven打包war及运行war包
pom.xml修改打包类型pom改为war <artifactId>Test02</artifactId> <packaging>war</packaging ...
- iOS学习笔记(4)——显示单组件选取器
1. 创建工程 创建新工程,create a new Xcode project 创建single view application 创建名为PickerViewTest的工程 2. 创建xib文件 ...
- iOS学习笔记(3)--初识UINavigationController(无storyboard)
纯代码创建导航控制器UINavigationController 在Xcode6.1中创建single view application的项目,删除Main.storyboard文件,删除info.p ...
- Ubuntu下解决apt update时签名无效问题
Ubuntu 18.04在执行apt-get update时出现一下报错: W: GPG 错误:http://repo.mysql.com/apt/ubuntu bionic InRelease: 下 ...
- 2016级算法第六次上机-D.AlvinZH的学霸养成记V
1081 AlvinZH的学霸养成记V 思路 中等题,计算几何. 这是一个排序问题,按极角排序.可以转化为叉积的应用,对于点A和B,通过叉积可以判断角度大小,共线时再判断距离. 叉积的应用.OA × ...
- 2016级算法期末模拟练习赛-C.AlvinZH的青春记忆II
1084 AlvinZH的青春记忆II 思路 中等题,二分. 简化题意,一列数字,每秒会自动-1,特殊操作可以使一个数在1s内-k,问这些数都减至0需要多久. 答案肯定在[1,xMax]之间,采用二分 ...
- app.module.ts说明
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; ...