02-java数据类型及运算符

回顾

Java历史及发展

  • Java是由sun公司在1995年发布,至今已有25年(目前最新版本为jdk15,稳定版本为jdk11,但是用的最多主流版本jdk8

Java语言的特点

  • Java语言是面向对象的高级语言,Java的核心优势就是跨平台,也被称为“一次编译,到处运行”。

搭建Java开发环境

  • Java开发环境搭建,JDK按照配置环境变量:JAVA_HOME、CLASSPATH、Path。
  • 可能遇到的问题:



CLASSPATH:;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib;%JAVA_HOME%\tools.jar; 
--单行
  • 或者是
C:\Program Files\Java\jdk1.8.0_111\lib<br/>C:\Program Files\Java\jdk1.8.0_111\tools.jar<br/>C:\Program Files\Java\jdk1.8.0_111\lib\dt.jar 
--多行 -- win10

Java程序开发过程

  • 常用命令
  javac + 文件名.java
  java + 类名
  javadoc + 文件名.java
  • 命名规范:驼峰式,类名首字母大写,方法名首字母小写
  • Java 支持三种注释方式。前两种分别是 // 和 */ */,第三种被称作说明注释,它以 / 开始,以 ***/**结束。
  • eclipse中快捷键
  • ctrl+?/ 单行 ctrl+shift+?/ 多行加注释 返回来 ctrl+shift+\

目标

  • 基本元素
    • 标识符 、字符集 、关键字 、常量与变量
  • 数据类型
    • java的八大基本数据类型 -- 内存大小 默认值
    • 常量变量的定义和使用以及内存的空间分配
    • 数据类型转换 -- 隐式转换(小类型->大型) 显式转换(大->小)强制转换,强制转换符(低类型的数据类型)
  • 运算符
    • 掌握赋值、算术、关系和逻辑运算(|&~)符,了解位运算符^
    • 熟悉掌握赋值、算术、表达式
    • 熟悉掌握运算符的优先级和结合方向

基本元素

标识符

  1. 标识符是赋给类、方法或变量的名字。
    • 凡是可以由自己命名的地方都称为标识符。
    • 例如,对于常量、变量、函数、语句块、类、项目等都需要一个名字,这些我们都统统称为标识符。
    • --涉及给Java进行命名,叫标识符。--- 尽量做到 见名知意
  2. 组合:字母、美元符($)、下划线(_)或数字的任何字符组合。
  3. Java中区分大小写;
hello
Hello    这两个文件不属于同一个文件
  1. 在Java中一个合法的标识符,正确的命名:
    • 只能是 数字、字母、下划线(_)和美元符号($),
    • 但不能以数字开头,
    • 不能是关键字,
    • 不能有空格。
    • 字母事实上,不仅仅包含英文字母(26),还包含中文以及各个国家的母语——字符集,java用Unicode字符集
    • 为什么不能以数字开头
 验证为什么。
 在“常量与变量”中,我们知道变量是用来存储数据,如果变量名可以以数字开头,那么也可以以数字结尾,
 eg:
    int a = 123;   
    int 234 =5; 
    234 == a ?

关键字

1、主要记住常用的几个就好,“String”“main”不是关键字
2、保留词(无含义但不能使用):goto, const -->在C语言/C++中
3、不能用关键字命名,但是可以包含关键字。

字符集

java使用Unicode标准字符集,最多可以识别65536个字符,Unicode字符集的前128个字符是ASCII码表.

  1. 常见字符集名称:ASCII字符集、GB2312(GBK)字符集、BIG5字符集、 GB18030字符集、Unicode字符集等。
  2. Unicode(统一码、万国码、单一码)涵盖了世界上所有文字和符号的字符编码方案。为每种语言中的每个字符设定了统一并且唯一的二进制编码。
  3. Unicode表示主要UTF-8,UTF-16,UTF-32。
  4. UTF-8:单字节来表示字母,双字节来表示一些希腊字母,三字节来表示汉字。
  5. 在Unicode字符集中,一个字符占2个字节(16位)。一个字节占8个bit位
  6. Java语言用的字符集是16位Unicode编码,所以支持中文。
  7. 转义字符:


命名规则

Java编程一般用驼峰命名法命名,对多个单词进行大小写的间隔。


项目名 :首字母大写


类名和接口名:每个单词的首字母,其余为小写。(大驼峰)方法名:第二个单词起的首字母为大写,其余全为小写。(小驼峰)常量名:基本数据类型的常量名使用全部大写字母,字与字之间用下划线分隔

包名xxxyyyzzz全小写
类名、接口名XxxYyyZzz首字母大写
方法名、变量名xxxYyyZzz首字母小写
常量名XXX_YYY_ZZZ全大写

常量与变量

  • 常量就是一个保持不变的值。常量不能进行二次赋值。
910
  • 变量是Java程序的一个基本存储单元。变量由一个标识符,类型以及一个可选初始值组合定义。

(就如在数学的方程式x,y。而java中也有类似,我们一般称变量。一般用来做数据计算或者传递)

//变量就像是有名字的容器用来存储稳定不变的常量。
a = 5;
  • Java是强类型语言,在声明变量时要指定数据类型。
// 变量的组成定义: 类型 变量名 [= 初始值] [, 标识符[=初始值]…]  
int a,b,c;	    int d=5,f=18;
char x = ‘x’;
final int y = 5;

注意:

  1. 在方法中声明的变量没有初始值,如果去使用这个变量,会编译报错。
  2. Java中一般用final关键字修饰变量表示常量,该变量不可改变。

变量内存的空间分配

  • 程序要为每一项数据分配内存,通常使用变量来存储数据。使用变量可以引用存储在内存中的数据,并随时根据需要显示数据或执行数据操纵。
    • 变量申请内存来存储数据,并对内存中的数据进行访问和修改。
    • 也就是说,当创建变量时,需要在内存中申请空间,内存管理系统根据变量的类型为变量分配存储空间。

但是程序怎么去调用?通过变量,找到存储在内存中的数据,
说到底,变量就相当于为内存地址提供了一个有意义的名称。
而变量的具体地址是什么,我们不用管,操作系统会去记住内存地址
所以我们只需要指定“变量名” -->内存空间的值

基本数据类型

Java两大数据类型:基本数据类型+ 复合数据类型(内置数据类型+引用数据类型)

八大基本类型

  • 布尔类型 boolean(只作为一种标志来记录 true/false 情况;默认值是 false;)
boolean b1 = true;
boolean b2 =false;
boolean b3;//默认值false
  • 四个整型(byte-8位、short-16位、int-32位、long-64位,都是有符号的)
  • 1)byte 数据类型是8位、有符号的以二进制补码表示的整数;最小值为-2^7
  • 最大值为2^7-1
  • 两个浮点型(float-32位单精度 例:float f1 = 234.5f 、double-64位双精度 例子:double d1 = 123.4)
  • 注意:

1)浮点数通常是实际值的近似值;浮点数不能用来表示精确的值,如货币

float ff = 21.9f/3;//7.3
float ff = 21.999f/3;//7.333

2)float型变量 表示的常量后必须加上F/f

  • float double取值范围如下:
  • 对于单精度浮点数(float)来说,有一位符号位,指数位共8位,尾数共复23位。指数能够表示的指数范围为-128~127。尾数为23位。当尾数全1时再加上小数点前面的1,指数取到最大正数127(8位,正数最大127,负数最小-128),浮点数取得制正数的最大值。
  • +1.111111111111111111111*2^127(1.后面23个1,由于尾数的范围1~2,其最知高位总为1,故只需存取小数部分,所以小数为是23位1),约等于
  • 2 _2^127=3.4 _10^38。道为3.4 *10^38负数亦然。
  • Double的计算与此类似,double的符号位为63位,指数为62~52位,共11位。表示的范围为-1024~1023。尾数为51~0。表示的范围为+1.111111111111111111111_2^1023(1.后面52个1)为1.7 _10^308。负数亦然。
  • 字符型 char (单一的 16 位 Unicode 字符) ---无符号的数据类型
    • char类型必须用单引号来表示
    • 单引号中,可以输入字符的Unicode值,Unicode表示法是在值前加前缀\u 比如,\u00000(小于或者等于65535)
    • 如果要表示一个不能作为字面值输入的字符,可以使用转义字符 char d='\n'; 换行,新行,水平制表符,退格,双引号和单引号 \b \t \n \f \r " '
char a =  '\u1010'; //直接输入字符的Unicode值,在值前加前缀\u
char b1 ='a'; //单引号表示单个字符
char b2 ='\n'; //无法表达的字面意思 通过转义字符表示
char b3 = 97;  //整数。0~65535。十进制、八进制、十六进制均可。输出字符编码表中对应的字符。
  1. byte取值范围(-128~127)按照通常直觉,正负数不是对称的吗,为什么负数最小不是-127,又或正数最大是128呢?在思考这个问题的时候先来熟悉下怎么计算二进制和十进制之间的转换
  • 1)十进制转二进制采用短除法,二进制转十进制采用权相加法
短除法:十进制8转换成二进制 0000 1000
算术  商 余数
8/2   4  0
4/2   2  0
2/2   1  0
1/2   0  1  
之后在余数部分从低 到 高 读,得到的值就是十进制
注:十进制转八进制/十六进制 也一样。


权相加法:二进制转十进制
1000 = 1*2^3 + 0*2^2 + 0*2^1 + 0*2^0 = 8
  • 2)二进制转八进制,3位二进制按权展开相加得到1位八进制数(取3合1),主要是因为八进制是“逢8进1”所以取值范围0~7 ,在二进制里,111表示7。八进制转成二进制,每位为3个二进制数,短除法得到二进制数不足3位高位补零。
  二进制10110 转 八进制
  取三合一,高位不足补0 => 010 110 =>    
  010=0*2^2+1*2^1+0*2^0=2  
  110=1*2^2+1*2^1+0*2^0=6
  10110 = 026(以0开头表示八进制)
  • 3)二进制转十六进制方法为:与二进制转八进制方法近似,八进制是取三合一,十六进制是取四合一。(注意,高位不足4位时补0)。
  • byte 是8位,二进制表示 :0000 0000 ~ 1111 1111 总共能够表示2^8 = 256个数。在Java中整型都是有符号,区分就看第一个比特位,第一个bit位:0为正1为负
  • 所以byte 正数取值 0000 0000 ~ 0111 1111 0 , 127 共8位数
  • 负数取值 1000 0000 ~ 1111 1111 -128 , -1 共8位数 负数用补码。原码取反+1

int 0000 0000 0000 0000 0000 0000 1100 1000 =200
byte 1100 1000 = -56

数据类型转换

数据类型的转换前必须了解它们之间占内存的容量大小和表示的范围。


低---------------------------->高


byte(8), short, char(16) > int > long > float > double


优先级:字符型 < 整型 <浮点型,在同类型中优先级是按照内存大小进行划分,小内存优先级<大内存。 隐式(自动类型)转换


转换一般是从低优先级的数据类型 至 高优先级的数据类型。


低优先级类型 --> 高优先级类型





注意:char的类型比int低

char ch = ‘A’;//97=a     相差32   A=65
int in3 = ch;
system.out.println("in3="+in3); //65
//直接将该字符所在Unicode表中的位置序号赋值给整型int变量。

强制类型转换


从高类型 --> 低类型,需要强制转换符实现强制转换。


强制转换符:(需要转换成的类型)变量





注意:int转char、浮点型 转 整型

int in4 = 97;
char ch1 = (char) in4;
system.out.println("ch1 ="+in4);
//表示将该字符所在Unicode表中的位置序号的字符赋值给字符ch1变量。
 
double dou2 = 18.9;
int in5 = (int) dou2; //18
//浮点型的值赋值给整型变量时,直接舍弃小数部分,只给正数部分。

表达式的类型转化


java中整数类型默认的int类型;小数类型默认的double。


整数表达式包括byte、short、int表达式的类型自动被提升到int。约定如果一个操作数是long整个表达式被提升到long,float和double一样。

byte by1= 10;
int in1= 20;
int in2=by1+in1;//byte,int相加后类型取高精度int;
byte by2 = (byte)(by1 + in1);//byte,int相加后类型取高精度int;需要强转

注意:


1)从低类型到高类型,不需要强制转换符。


2)高类型->低类型,转换过程中可能导致溢出或损失精度。

byte by1= 10; //-128~127
int in1= 200;
byte by2 = (byte)(by1 + in1); //数据溢出
system.out.println("by02="+by02); //-46
    
double dou1 = 1.33;
int in2 = 10;
int in3 = (int)(dou1 + in2); //精度丢失
system.out.println("in3="+in3); //11

3)不参与运算,整数可以直接赋值给byte,short,char,不需要强转。

byte by1=12,by2=34; //8位
byte a6 = (byte) (by1 + by2);//参与运算需要在运算前加强制转换符

4)boolean类型不进行类型转换。


5) 不能把对象类型转换成不相关类的对象。(后面涉及继承子类和父类之间的转换)


运算符

表达式

1、表达式定义:用运算符、括号将 操作数 连接起来的,符合Java语言语法规则的式子。

  1. 操作数:变量、常量或函数
  2. 运算符:
    • 根据操作数数量分:一元运算符(加加++、减减--)、二元运算符(加号+)、三元运算符
    • 根据用途分:赋值运算符、算术运算符、关系运算符、逻辑运算符、位运算符 等等。
    • 运算符有优先级和结合方向:
      • 优先级高低次序执行:eg:先乘除后加减
      • 结合方向:左结合(左边开始计算)、右结合(右边先计算)
  3. 表达式:算术表达式、关系表达式、逻辑表达式、函数表达式

算术运算符

+、-、*、/、%(求模) =>二元


一元减- (做负数)、递增++、递减-- =>一元


(次)演示代码:

int a = 10;
int b =3;
//请大家自己用算术运算符加减乘除,求模进行验证一下。

1、(重点) 递增 i++ 和 ++i

  1. **i++**含义:先获取 i 的值,再i 自增加一

2)++i含义:先对 i 自增加一,在取i的值

// i++含义:先获取i值,再进行i+1
// ++i含义:先进行i+1,再取值。
int i=10;	
System.out.println(i++);//先打印i的值,再i自加	
System.out.println(i);//11
System.out.println(++i);//12
System.out.println(i);//12
System.out.println(--i);//11
System.out.println(i);//11
System.out.println(i--);//11
System.out.println(i);//10

赋值运算符

“=”就是赋值运算符,作用将表达式的值赋给一个变量。语法:变量名 = 表达式,右结合。

//可以将同一个值赋给多个变量,多重赋值。
int in01 =1;
int in02 ,in03;
in02 = in03 = in01;
、//int in02 = in03 = in01;


//右结合  从01>03>02
	System.out.println("in02="+in02+",in03="+in03);

赋值表达式:


1)由赋值运算符或者复合运算符,将一个变量和一个表达式连接起来的表达式,成为赋值表达式。


2)表达式的值通俗的理解就是,等于号的左边的变量。

复合赋值运算符

+= 、 -= ,*=, /=,%=


相当于缩写,eg X += 1 --> X = X+1

//复合赋值运算符
//+=,-=,*=,/=,%=
int x=10;
int y=5;
x += y;
System.out.println("x1="+x);
x -= y;
System.out.println("x2="+x);
x *= y;
System.out.println("x3="+x);

关系运算符

主要是判断两个值的关系,是大于、小于还是等于,所以他们计算的结果只有正确与否,Java中用true或false。

//关系运算符
//>,<,>=,<=,==,!= //两边的数据类型必须一致. 整型>string
//关系表达式的计算结果为 布尔类型boolean
int a = 10;
int b =11;
boolean flag = a>b;  //false

注意:>,<,>=,<= 只有数字才能比较大小;


== ,!= 等号两边类型保持一致

//flag = 10>"gok" //两边必须是数字;
flag = 10>'a'; //此时,默认把字符隐式转换成整型,所以可以把字符型当作数字。


flag = “goktech” == "gok";
flag =  11 == 11;//两边同类型。
system.out.println(flag);

逻辑运算符

  1. 与:表达式1 && 表达式2 ,含义:当且仅当两个表达式均为true时,则整个表达式运算结果为true。 所以 &&,有假必假
    • 与 &
  2. 或:表达式1 || 表达式2 ,含义:当且仅当两个表达式均为false时,则整个表达式运算结果为false。 所以 ||,有真必真 当表达式1 是真 表达式2 为假=> 真
    • 或 |
  3. 非:! 表达式,含义:取反 !true => false
int a1 =10,b1=9,c1=15;
boolean flag = a1<b1 && c1<a1; //false //其实,只判断左边 -->  短路现象
System.out.println("flag="+flag);
flag = a1>b1 || c1<a1; System.out.println("flag="+flag); ``` -  短路现象: 1. 与&&短路:如果表达式1为假,则直接可以判断整个表达式 为flase,所以忽略表达式2的计算。 2. 如何避免短路现象,直接用  &,非短路与&,不管左边表达式的值为多少,右边表达式总要参与运算。  3. 但今后的开发过程,一般常用 &&。 ```java //短路与非短路现象:  int ii =10; flag = a1>b1 && ++ii>1; 
System.out.println("flag="+flag);
System.out.println("ii="+ii); //11
//短路现象,如果表达式1 为假则直接忽略第二个表达式的计算
flag = a1<b1 & ++ii>1; 
System.out.println("flag="+flag);
System.out.println("ii="+ii); //11

位运算符

定义 二进制 针对每位 进行一个运算。


位运算符:&、|、~、^


8 = 1000 =1*2^3


其中,异或^,可以用来加解密,连续异或两次得到原来的值。

/*               
 * 位运算符:&、|、~、^
 * 进行位运算之前得把相应数据转换成二进制再按位计算   
 * 其中,异或^,可以用来加解密,在网站项目设计的时候可
 * 异或有个规则:相同才为0,不同为1
 */                                                   
int myInt01 = 5 ^ 1;//101 ^ 001 =100                  
System.out.println("myInt01="+myInt01);               
//利用 异或加解密:                                   
char pwd = '国';                   
char key ='科';
//加密
char pwd2 = (char) (pwd^ key); //类型不匹配,异或的计算结果是整型int
//解密
char pwd3 = (char) (pwd2 ^ key);