2.偏头痛杨的Java入门教学系列之变量&数据类型篇

复习
1.Java为什么能跨平台?
2.Java抄了哪个编程语言?
3.Java是由哪个公司搞出来的?
4.Java的爸爸是谁?
5.Java的工作机制?
6.JDK&JRE&JVM分别是什么以及他们的关系?
7.Java的应用场景?
8.java与javac命令的作用?
9.Java环境如何配置? 
10.Java的部分特点?

前文链接
1.偏头痛杨的Java入门教学系列之认识Java篇
http://blog.csdn.net/piantoutongyang/article/details/70138697


前戏
编程时,其实大部分时间都是在跟数据的存储打交道,那需要使用什么东西做临时存储呢?
答案是变量。变量前面需要定义数据类型,来限定变量里具体存储的数据的类型,
那么今天我们就来聊聊变量与数据类型。
这两个概念是Java中的核心概念,如果学不会,后面的学习将如履薄冰。


变量&数据类型
变量是指在程序的运行过程中随时可以发生变化的量,Java使用变量临时存储各种数据,
是存储数据的基本单元,创建变量的时候,需要在内存中申请空间。
例如:用户在界面中输入了一个数字,我们要用变量存储这个数字供以后使用。

变量必须要先定义(声明),再初始化(也可以不初始化,有默认值),之后才能使用。
那每个变量都是存储的什么样的数据呢?这就衍生出来一个概念,数据类型。

数据类型用于约束变量中内容的类型,需要为每个变量指明一个具体的数据类型。
数据类型确定要存储在内存中的数据的类型。
内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。
例如:数据类型是字符串的变量,那么这个变量只能存储字符串,不能存储数字。
2.偏头痛杨的Java入门教学系列之变量&数据类型篇_第1张图片
因此,通过定义不同数据类型的变量,可以在内存中储存整数、小数或者字符等数据类型的数据。

变量分为三种:类变量&静态变量、实例变量、局部变量,
这些知识会在后面的初级面向对象篇文章中展开。


变量的Java语法(需要背)
[修饰符] 数据类型 变量名 [= 初始值];
public String name = "frank";
private String name1;
static int age = 20;
double b = 0.111;
Person p ;
String a = "张三",b = "李四";//变量还可以这样定义,但不推荐。
修饰符:变量被final、private、protected、public、static等关键字修饰,
具体关键字的定义在以后会介绍。

数据类型:基本数据类型与引用数据类型,例如:int是整型,String是字符串等等,
细节在下面展开。

变量名:首字母必须小写。

初始值:可以没有,如果没有则系统会给一个默认值,
具体默认值要根据具体的数据类型而定。

"=":等号表示赋值,将等号左边右边的值赋给了等号左边的变量。

";":分号表示一句话的结束。
class  Hello{
   public static void main( String args[ ]) {
        double salary;  //声明变量
        salary = 1500.00;  //变量赋初值,也可以简化成一句double salary = 1500.00;
        System.out.println(salary);   //访问变量
   }
}
Java强制要求必须定义变量的数据类型,所以说Java是强类型语言。
像Javascript则没有这种要求,所以说Javascript是弱类型语言。
一般说来,在创建大型程序时,强类型有助于减少程序错误。

Java的数据类型分为:基本数据类型和引用数据类型。
在Java中有8种数据类型来存储数值(整数,小数)、字符和布尔值。
除了8种基本数据类型以外,其他所有的数据类型都被统称为引用数据类型。 2.偏头痛杨的Java入门教学系列之变量&数据类型篇_第2张图片


基本数据类型
整型(整数类型):byte,short,int,long
整数型用来存储整数数值,即没有小数部分的数值。可以是正数,也可以是负数,默认是int类型。

byte
1个byte类型整数在内存里占8位(1个字节),
表数范围-128(-2的7次方)~127(2的7次方-1),
byte类型用在大型数组中节约空间,一般用于文件流等,主要代替整数,
因为byte变量占用的空间只有int类型的四分之一;
byte a = 50;
byte b = -100;

short:
1个short类型整数在内存里占16位(2个字节),
表数范围-32768(-2的15次方)~32767(2的15次方-1)
short数据类型也可以像byte那样节省空间。一个short变量是int型变量所占空间的二分之一;
short a = 1000;
short b = -2000;

int:
1个int类型整数在内存里占32位(4个字节),
表数范围-2147483648(-2的31次方)~2147483647(2的31次方-1)
一般地整型变量默认为int类型;
int a = 100000;
int b = -200000;

long:
1个long类型整数在内存里占64位(8个字节),
表数范围-9223372036854775808(-2的63次方)~9223372036854775807(2的63次方-1)
long类型的整数是以L或者l在结尾表示,不要写小写的L,因为会与数字1混淆。
这种类型主要使用在需要比较大整数的系统上;
long a = 100000L;
long b = -200000L;

小贴士
字节:此处为存储空间大小,变量存储在内存中的大小;
表数范围:变量可以赋多大的数值;

表数范围的例子:
byte a = 127;//正确
byte b = 128;//错误
(注意:内存是一种有限的资源,不要无休止的滥砍滥伐。)

Java中整数有4种表示方式(新手可自动PASS掉2,8,16进制)
1.十进制:每位可以写0~9,注意第一位不能是0。
int a = 10;//输出10
int b = 50;//输出50
2.二进制,必须以0b或0B开头,可以写0~1。(在JDK1.7之后才有)
int a = 0b11101001;//输出233
int b = 0B00000001;//输出1
int c = 0B00000010;//输出2
3.八进制,必须以0开头,可以写0~7。
int a = 07;//输出7
int b = 017;//输出15
int c = 0123;//输出83
4.十六进制,必须以0x或0X开头,可以写0~9,A~F,a~f。
int a = 0X8A;//输出138
int b = 0x1f;//输出31
(不要认为看到定义的整型变量被赋值上字母是一件很奇怪的事情。)


字符型:char
单个字符用char类型表示,必须使用单引号括起来。
char:1个char类型整数在内存里占16位(2个字节),
表数范围0~65535(2的16次方),无符号位,char数据类型可以储存任何字符;

Java中字符有4种表示方式
1.作为整数值
16位无符号整数(不能是负数),0~65535,但这里并不是表示真正地数字而是ASCII码。
支持四种整型表示方式,分别为:二进制、八进制、十进制、十六进制。
不要认为看到定义的字符变量被赋值上整数是一件很奇怪的事情。
char x = 96;//表示'字符
//下面4个char变量都输出'a'
char a = 97;//十进制的97
char b = 0x61;//十六进制的97
char c = 0141;//八进制的97
char d = 0b1100001;//二进制的97
char e = 'e';
char f = 'f';
System.out.println(e+f);//输出为203,是ASCII码的数值相加
小贴士:
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)
是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。
它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。

在计算机中,所有的数据在存储和运算时都要使用二进制数表示
(因为计算机用高电平和低电平分别表示1和0),
例如,像a、b、c、d这样的字母(包括大写)、以及0、1等数字还有一些常用的符号
(例如*、#、@等)
在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,
当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,
那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了ASCII编码,
统一规定了上述常用符号用哪些二进制数来表示。

ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。


2.单个字符(英文字母与汉字与符号)
char a = 'a';
char b = 'C';
char c = '我';
char d = '~';
3.转义符
转义字符
含义
\r
表示接受键盘输入,相当于按下了回车键
\n
表示换行
\t
表示制表符Table键
\b
表示退格键,相当于Back Space
\'
相当于单引号'
\"
相当于双引号"
\\
表示一个斜杠\
char a = '\n';
String b = "bbb";
String c = "ccc";
System.out.println(b+a+c); //输出bbb回车ccc
System.out.println(b+c);//bbbccc
4.Unicode值
格式为'\uxxxx',Java使用UTF-16,使用4位16进制数字表示,支持所有书面语言的字符,包括中文。
最小值为'\u0000',最大值为'\uffff'
char a = '\u8888';//输出'袈'
小贴士:
Unicode又称为:统一码、万国码、单一码,是计算机科学领域里的一项业界标准,
包括字符集、编码方案等。
全球所有的文字,都可以用Unicode码表示,超过65,000个字符,而ASCII只有128~256个字符。

Unicode为每种语言中的每个字符设定了统一并且唯一的二进制编码,
以满足跨语言、跨平台进行文本转换、处理的要求。
1990年开始研发,1994年正式公布。

比较有趣的是,下面4个变量都表示'a'。
char a = '\u0061';//unicode值
char b = 97;//十进制的ASCII码所对应的字母
char c = 0141;//八进制的ASCII码对应的字母
char d = 'a';//单个英文字符
注意:
1.char在正常开发中出镜率不是特别高,一般使用String字符串类型,
String类型可不是基本数据类型哟,而是一个类。
2.String除了不能表示整数ASCII码外,其余char的表示方式String都支持。
3.char使用单引号'',String使用双引号""。


布尔类型:boolean
boolean类型适于逻辑运算,一般用于程序流程控制。
boolean 数据类型有两个值:true和 false(不带引号), 默认值是false
boolean a;
a = true;

boolean b = false;
boolean flag = true;
if(flag){
  System.out.println("yes~");
}
if(flag==false){
  System.out.println("no~");
}


浮点型:float,double
带小数点的数值均可使用浮点类型表示,float为单精度浮点类型,double为双精度浮点类型。
在java里面小数默认为double类型,后面加f或F表示float类型 。

需要注意的是,float与double均不能进行精准小数运算,
因为底层二进制无法精准表述带小数点的十进制数,通常的解决方案是使用BigDecimal。
//浮点数无法进行精准运算,因为底层二进制无法精准表述带小数点的十进制
double a = 2.0 - 1.8;
//输出0.19999999999999996
System.out.println(a);

float b = 2.0f - 1.8f;
System.out.println(b);

//解决方案
BigDecimal b1 = new BigDecimal("2.0");
BigDecimal b2 = new BigDecimal("1.8");
System.out.println(b1.subtract(b2).doubleValue());
float:1个float类型浮点数在内存里占32位(4个字节),表数范围-3.403E38~3.403E38。
后缀为F与f均可使用,float在储存大型浮点数组的时候可节省内存空间;
float a = 234.5f;
float b = 234.0F;
float c = 33f;//输出33.0
double:1个double类型浮点数在内存里占64位(8个字节),表数范围-1.798E308~1.798E308。
用double类型的数据进行运算的时候结果会尽可能的精确。
后缀为D与d均可使用,默认不加后缀 ;
double a = 123.4;
double b = 12345.0;
double c = 110D;//输出110.0
double d = 120d;//输出120.0

Java中浮点数有3种表示方式
1.十进制形式:包含一个小数点,例:5.12,512.0,0.512,3.1415926F等。
float a = 3.141566666666666666F;//输出3.1415668
double b = 3.141566666666666666;//3.141566666666667
2.科学计数法:5.12e2(即5.12*10的2次方),只有浮点类型才能用科学技术法,E与e均可使用。
double a = 5.12e-2;//输出0.0512
double b = 5.12e2;//输出512.0
3.表示溢出或出错(新手直接跳过)
正无穷大:正数(不是正整数,而是正的小数)除以0,
用Double.POSITIVE_INFINITY或Float.POSITIVE_INFINITY表示。
负无穷大:负数(不是负整数,而是负的小数) 除以0,
用Double.NEGATIVE_INFINITY或Float.NEGATIVE_INFINITY表示。
非数:0.0除以0.0或对负数开方(例如:根号-2),用Double.NaN或Float.NaN表示。

所有正无穷数值相等+∞=+∞;
所有负无穷数值相等-∞=-∞;
非数不会与任何相等,包括非数,NaN≠NaN;
//正无穷大
double a = 6.0 / 0;//输出Infinity
double b = 255.0 / 0;//输出Infinity
double c = Double.POSITIVE_INFINITY;//输出Infinity
System.out.println(a==b);//输出true
System.out.println(a==c);//输出true

//负无穷大
double d = -15.0 / 0;//输出-Infinity
double e = -244.0 / 0;//输出-Infinity
double f = Double.NEGATIVE_INFINITY;//输出-Infinity
System.out.println(d==e);//输出true
System.out.println(d==f);//输出true

//非数
double g = 0.0/0.0;//输出NaN
double h = Double.NaN;
System.out.println(g==g);//输出false
System.out.println(g==h);//输出false

数据类型的默认值
当变量没有被赋值的时候,会有默认值,根据不同的数据类型来区分不同的默认值。
数据类型
默认值
byte
0
short 
0
int
0
long
0L
float
0.0f
double
0.0d
char
'\u0000'
String&object
null
boolean
false
注意:String字符串不是基本数据类型,而是引用数据类型。


基本数据类型转换
在Java中经常会出现多种数据类型进行混合运算,
不同的数据类型必须先转换成同一类,才能进行运算。
Java中有两种数据类型转换方式:自动类型转换、强制类型转换。

先来记住一个口诀:
从小到大自动转;
从大到小强制转;
强制类型转换会有溢出风险,就像有两杯水:
1.一大满杯与一小空杯,大杯的水倒满小杯后会溢出来。
2.一大空杯与一小满杯,小杯的水倒满大杯后并不会溢出。

自动类型转换(隐式类型转换)
目标类型的取值范围要大于源类型
(例如:int大于byte,那么byte就可以自动转成int)。
byte->short->int->long->float->double(从小到大)
char->int->long->float->double(从小到大)
byte a = 4;
int b = a;//byte可以自动转换成int,因为int比byte大。

char x = 4;
int y = x;

long i = 4;
float j = i;

表达式类型的自动提升:
当一个算术表达式中包含多个基本数据类型的值在进行混合运算时,
整个表达式的数据类型将发生自动提升,
自动将所有数据类型转换成容量最大的数据类型,然后进行计算。

规则:
1.所有的byte,short,char之间不会相互转换,首先会自动升为int。
2.整个表达式的类型自动提升到与表达式中最高等级操作数同样的类型
(操作数的等级排列,从大到小:double->float ->long->int )
double a = 1;
int b = 2;
System.out.println(a+b);//输出3.0

byte d = 1;
byte e = 1;
int g = d+e;//2个byte相加,结果是int。
byte f = (byte)(d+e);//2个byte相加,结果是int,int需要强转成byte。

强制类型转换(显式类型转换)
容量大的数据类型转换为容量小的数据类型时,需要强制类型转换,需要显式的定义。
(例如:byte小于int,那么byte必须要强制转成int)。
语法:变量 = (目标类型)值;
double->float ->long->int->short->byte(从大到小)

进行强制类型转换时一定要谨慎,因为整数类型进行强制转换时会发生溢出,
浮点数进行强制转换时会发生精度失准的情况,就像碗小,水放的多了会溢出一样。
int a = 123456789;
byte b = (byte)a; //进行强制类型转换,b=21,因为发生溢出。

int c = 1;
byte d = (byte)c;//进行强制类型转换,d=1,没有发生溢出。

注意:
boolean无法转换成其他数据类型;
char的字符被转成int,变成对应的ASCII值;
浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入;


引用数据类型
除了8种基本数据类型以外的所有数据类型,都是引用数据类型。
(在Java中,引用类型的变量非常类似于C/C++的指针。)

类(Java官方以及第三方的类库+我们自己定义的类)、数组、接口都是引用数据类型。
所有引用类型的默认值都是null,主要是用类、数组、接口等作为数据类型来声明一个变量。
关于引用数据类型方面的知识会在面向对象初级篇中还有介绍。
Person p1 = new Person();
//Person类型的变量p1引用了Person类的实例(变量p1指向了Person类的实例的引用)
//新手玩家可以pass,因为涉及到Java堆栈内存:new Person()会生成一个Person对象的引用,
这个引用指向了p1变量。

//分解动作
Person p1;
//用Person类作为数据类型来声明一个变量p1
p1 = new Person();
//使用new关键字调用Person类的构造方法来实例化对象,
//将对象的引用指向给p1变量(将对象赋值给了p1变量),
//那p1就变成了Person对象的引用,或者说变量p1引用了Person类的对象。

//注意:p1不是对象,而是对象的引用。

NULL
null代表声明了一个空对象,或者不确定的对象,即还没有分配内存空间,
对空对象做任何操作都不行,
除了使用"="与"=="。
一般用在是一个对象引用指向空(基本数据类型无法设为null),释放内存,
让一个非null的引用类型变量指向null。
这样这个对象就不再被任何对象应用了。等待JVM垃圾回收机制去回收。
Person p1 = new Person();//变量p1指向Person对象
p1 = null;//变量p1指向空。

常量
常量在程序运行时,不会被修改的量。 在 Java中使用final关键字来修饰常量,
声明方式和变量类似。
通常使用大写字母来定一个常量(常量必须显示的赋初值)
final String NAME = "张三";//无法修改name的值
final int AGE = 18;

final Person P1 = new Person();//引用类型可以修改其属性,但不能修改对象的引用
P1.name = "李四";
P1.name = "王武";
P1 = null;//出错,不允许这样
注意(新手略):
当final修饰引用变量时,它保存的仅仅是个引用,final只保证引用类型变量所引用的地址不会改变,
即一直引用一个对象,但这个对象的属性可以发生变化。
final Person p = new Person();
p.age = 18;
p.age = 20;//这样是允许的

基本数据类型封装类(包装类型)
8种基本数据类型还对应着8种包装类,包装类里有一些常见属性,
例如上面提到的表数范围、占多少位等,
以及提供一些工具方法可以做数据类型转换等操作,基本数据类型与包装类型的初始值不同,
例如int的初始值为0,而包装类则为null,用在JavaWeb开发中数据表映射成实体bean。

他们的对应关系如下:
byte->Byte
short->Short
int->Integer
long ->Long
float->Float
double-Double
char->Character
boolean->Boolean

String a = "5";
int b = (int)a;//无法直接将字符串转成整型
int b = Integer.valueOf(a);//因此需要使用包装类的方法来实现

// byte 
System.out.println("基本类型:byte 二进制位数:" + Byte.SIZE); 
System.out.println("包装类:java.lang.Byte"); 
System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE); 
System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE); 
System.out.println(); 

// short 
System.out.println("基本类型:short 二进制位数:" + Short.SIZE); 
System.out.println("包装类:java.lang.Short"); 
System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE); 
System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE); 
System.out.println(); 

// int 
System.out.println("基本类型:int 二进制位数:" + Integer.SIZE); 
System.out.println("包装类:java.lang.Integer"); 
System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE); 
System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE); 
System.out.println(); 

// long 
System.out.println("基本类型:long 二进制位数:" + Long.SIZE); 
System.out.println("包装类:java.lang.Long"); 
System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE); 
System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE); 
System.out.println(); 

// float 
System.out.println("基本类型:float 二进制位数:" + Float.SIZE); 
System.out.println("包装类:java.lang.Float"); 
System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE); 
System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE); 
System.out.println(); 

// double 
System.out.println("基本类型:double 二进制位数:" + Double.SIZE); 
System.out.println("包装类:java.lang.Double"); 
System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE); 
System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE); 
System.out.println(); 

// char 
System.out.println("基本类型:char 二进制位数:" + Character.SIZE); 
System.out.println("包装类:java.lang.Character"); 
// 以数值形式而不是字符形式将Character.MIN_VALUE输出到控制台 
System.out.println("最小值:Character.MIN_VALUE="+ (int) Character.MIN_VALUE); 
// 以数值形式而不是字符形式将Character.MAX_VALUE输出到控制台 
System.out.println("最大值:Character.MAX_VALUE="+ (int) Character.MAX_VALUE);

自动装箱&拆箱
自动装箱
把一个基本数据类型变量直接赋给对应的包装类变量,
或赋给Object(所有类的父类)变量。

自动拆箱
允许直接把包装类对象直接赋给一个对应的基本数据类型变量。
Integer inObj = 5;
Object boolObj = true;//装箱
int i = inObj;//拆箱

总结
今天我们主要学习了2大概念:变量与数据类型,这两个是java中的核心概念,密不可分。
以及详细的介绍了基本数据类型与引用数据类型的各种细节,
以及相关的数据类型转换以及包装类&常量&Null等概念,希望大家继续加油哟,
Java之路才刚刚开始呢。


作业
在main()中定义8个变量,分别对应8种基本数据类型,并输出他们的初始值,
之后再给他们赋值并输出。

你可能感兴趣的:(#,Java教学系列)