《Java开发实战经典》3-Java基础

目录

3.1 数据类型划分

  • Java数据类型分为基本数据类型引用数据类型
  • 基本数据类型,可以直接定义并使用,如图
  • 引用数据类型则是以一种特殊的方式指向变量实体 类似于C/C++中的指针 这类变量在声明时不会分配内存,必须另外进行开辟内存空间的操作

3.2 基本数据类型

  • 如果想在程序中使用一个变量,就必须先声明,此时编译程序会在未使用的内存空间中寻找一块足够能保存这个变量的空间以供其使用。
  • Java的基本数据类型如下图:

3.2.1 整数类型

  • 不带小数和分数的数据,可以声明为整数变量,如3、-100
  • 整数类型数据分为byte short int long4种 long为64位,占8个字节(bytes) int为32位,占4个字节(bytes) short为16位,占2个字节(bytes) byte为8位,即1个字节(bytes)
  • 正如上图所示,可以根据实际需要数值的大小,合理选定相应的类型,用于节省内存空间

比如声明一个短整型变量sum

short sum;
  • 经过声明之后,Java会在内存空间中寻找一个占有两个字节的块供sum变量使用,同时,这个变量的范围只能在-32768至32767之间

一个整型常量的默认类型是int 声明常量时最好不要超过它的范围

int num = 999999999999999;

运行报错:超出长度

3.2.2 数据的溢出

  • 当整数的数据大小超出了可表示的范围,而程序又没有做出数值范围的检查时,这时的输出结果不可预料,容易发生溢出

如:将整型的最大值加1和加2

public class TestDemo {
public static void main(String[] args) {
int max = Integer.MAX_VALUE;
System.out.println("整型的最大值:"+max);
System.out.println("整型的最大值+1:"+(max+1));
System.out.println("整型的最大值+2:"+(max+2));
}
}

运行结果:
整型的最大值:2147483647
整型的最大值+1:-2147483648
整型的最大值+2:-2147483647
  • 要解决溢出的问题: 可以选择在程序中加上数值范围的检查功能 或者用更大的数据类型来装下这个变量,如长整型long

因此稍作改动,可以避免整型数据溢出 比如在常量后加大写的L,或者在变量前加上long,作强制转换

System.out.println("整型的最大值+2:"+(max+2L));
System.out.println("整型的最大值+2:"+((long)max+2));

运行结果:
整型的最大值+2:2147483649
整型的最大值+2:2147483649

3.2.3 字符类型

  • 字符类型在内存中占两个字节,主要用来保存英文字符等字符 用单引号括起
  • Unicode是JAVA当前使用的字符编码系统 它为每个字符制定了唯一的数值
  • 小写的a是用数值97来表示,如果以字符变量形式来输出,会输出对应的字符

字符和整型的相互转换

public class TestDemo {
public static void main(String[] args) {
char ch1 = 'a';
char ch2 = 97;
System.out.println(ch1);
System.out.println(ch2);
}
}

运行结果:
'a'
'a'
  • 如果想在输出时用到双引号 这时候就需要使用转义字符

使用转义字符

public class TestDemo {
public static void main(String[] args) {
char ch1 = '\"';
char ch2 = '\\';
System.out.println(ch1);
System.out.println(ch2);
System.out.println("\"Hello World\"");
}
}

运行结果:
"
\
"Hello World"

3.2.4 浮点数类型和双精度浮点数类型

  • 下面介绍单精度和双精度类型floatdouble 适合表示用到小数点的数值 其范围都比较大,具体参考本节最上面的图
  • 在使用double时,数值后面可以不用加D或者d 而使用float时,数值后面需要加上标志F或者f 如果没有加上,会默认视为double类型

浮点型数据计算

public class TestDemo {
public static void main(String[] args) {
float num = 3.0f;
System.out.println(num*num);
}
}

运行结果:
9.0

##3.2.5 布尔类型

  • 布尔类型,即boolean变量,其值只有truefalse两种 如:
boolean flag = false;

  • 主要用于控制程序的流程

##3.2.6 基本数据类型默认值

  • 如果变量在声明后没有赋初始值,JAVA则会给它使用默认值 但是不建议过于依赖系统给变量赋初值 最好避免这种情况,当出现bug时,可能导致程序难以找到问题

#3.3 数据类型的转换

  • JAVA数据类型在定义的时候就已经确定,因此不能随意转换数据类型 但是允许用户有限度地做出类型转换处理 分为自动类型转换强制类型转换 ##3.3.1 自动类型转换
  • 自动类型转换需要符合以下两个条件: 1. 转换前的数据类型与转换后的数据类型兼容 2. 转换后的数据类型的表示范围要比转换前的大
  • 比如将short转换为int
    • 由于同为整数类型,因此符合条件1
    • int的表示范围比short大,因此符合条件2
  • 转换后,由大的范围表示原有小的数据,因此不会造成数值精确度的损失
  • 整数和浮点数是兼容的,但是与布尔类型就不兼容 因为boolean只能取true和false两种值

自动转换示例

public class TestDemo {
public static void main(String[] args) {
int x = 30;
float y = 22.19f;
System.out.println(x/y);
System.out.println(10/3.5);
System.out.println(10/3);
}
}

运行结果:
1.3519...
2.8571...
3

  • 可以看到,int和float做运算,结果被自动转换为float类型 int和int做运算,结果当然仍然是int类型
  • 还有一种比较特殊的类型是String
    • String类型是一个类,属于引用类型,但它可以像普通变量那样直接赋值来进行声明,字符串使用双引号""括起来,并通过"+"号进行连接
    • 任何数据碰到String类型,都会向String类型转换
public class TestDemo {
public static void main(String[] args) {
int i = 1;
int j = 2;
System.out.println("1+2="+i+j);
}
}

运行结果:
1+2=12

##3.3.2 强制类型转换

  • 整数和整数做运算,结果也是整数 如果是除法操作,结果需要显示小数点,此时就需要用到强制类型转换
  • 直接在变量前加上(),并在括号内填写需要转换的类型 由于是直接操作,因此也称为显式转换
public class TestDemo {
public static void main(String[] args) {
float f = 30.3f;
int x = (int) f;
System.out.println(x);
System.out.println((float) 10/3);
}
}

运行结果:
30
3.3333...

  • 首先将浮点型 f 赋值给整型 x 由于浮点型float的长度大于整型int的长度 属于把大范围的数值赋值给小范围数值 因此需要强制转换,因此损失了部分数值的精度
  • 接着是两个常量做相除运算,10用到了强制转换为float 因此结果必定也是float

#3.4 运算符、表达式、语句

  • 程序是由许多语句组成,语句的基本单位是表达式和运算符 ##3.4.1 运算符
  1. 赋值运算符 =
num=3;

  • 把3赋值给num
num=num-3;

  • 把num-3赋值给num
public class TestDemo {
public static void main(String[] args) {
int num = 22;
System.out.println(num);
num = num -3;
System.out.println(num);
}
}

运行结果:
22
19

  1. 一元运算符 + - !

比如:

public class TestDemo {
public static void main(String[] args) {
boolean b =false;
int x = 10;
int y = -30;
System.out.println(b +" "+ !b);
System.out.println(x +" "+ -x);
System.out.println(y +" "+ -y);
}
}

运行结果:
false true
10 -10
-30 30

  1. 算术运算符 + - * / %
  • 分别代表 加、减、乘、除、取余
  • 比如:
public class TestDemo {
public static void main(String[] args) {
int x = 10;
int y = 3;
System.out.println( (x+y) );
System.out.println( (x-y) );
System.out.println( (x*y) );
System.out.println( (x/y) );
System.out.println( (x%y) );
}
}

运行结果:
13
7
30
31
1

  1. 关系运算符 > < >= <= == !=

如:

public class TestDemo {
public static void main(String[] args) {
System.out.println( 3>1 );
System.out.println( 3<1 );
System.out.println( 3>=1 );
System.out.println( 3<=1 );
System.out.println( 3==1 );
System.out.println( 3!=1 );
}
}

运行结果:
true
false
true
false
false
true

  • 使用关系运算符去判断一个表达式成立与否时 若判断成立,会产生一个布尔值true 若判断不成立,会产生一个布尔值false
  1. 自增自减运算符 a++ a-- ++a --a
  • a++相当于a=a+1,同理,a--相当于a=a-1
  • a++++a的区别在于 a++会执行完整个语句后,再将a的值+1 而++a先将a的值+1,然后再执行整个语句
public class TestDemo {
public static void main(String[] args) {
int a=3, b=3;
int x=6, y=6;
System.out.println( "a++ ="+(a++) + " a="+a);
System.out.println( "++b ="+(++b) + " b="+b);
System.out.println( "x-- ="+(x--) + " x="+x);
System.out.println( "--y ="+(--y) + "y="+y);
}
}

运行结果:
a++ =3 a=4
++b =4 b=4
x-- =6 x=5
--y =5 y=5

  1. 逻辑运算符 & && | ||
  • 当使用短路与&&时 只有当运算符前后两个操作数的返回值都为真,结果才为真
  • 当使用短路或||时 运算符前后两个操作数中只要有一个为真,结果就为真
  • 参考如下:
  • 示例
public class TestDemo {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
System.out.println( a||b );
System.out.println( a|b );
System.out.println( a&&b );
System.out.println( a&b );
}
}

运行结果:
true
true
false
false

  • 此外,如果if语句需要同时判断多个条件,也可以使用逻辑运算符
int score = 50;
if((score<0) || (score>100)){
System.out.println("成绩有误");
}

  • 那么有个问题:&&与&、|与||有什么区别?
  • 从前面的图可以看出 1 对于&与操作来说,第一个条件为假,不管后面的条件真假,结果肯定为假 2 对于|或操作来说,第一个条件为真,不管后面的条件真假,结果肯定为真
  • 而区别在于 与&操作会要求所有条件都判断 或|操作会要求所有条件都判断 短路与&&,只要第一个条件为false,后面将不再判断,结果必定为假 短路或||,只要第一个条件为true,后面将不再判断,结果必定为真
  • 下面验证一下&&&
public class TestDemo {
public static void main(String[] args) {
if(10 != 10 & 10 / 0 ==0){
System.out.println("条件满足");
}
}
}

运行报错:除数不能为0

  • 如果是使用&,则会报错,除数不能为0 如果改为&&,则错误信息会消失,因为根本不会执行到10/0==0这里来
        if(10 != 10 && 10 / 0 ==0){
System.out.println("条件满足");
}

  1. 括号运算符()
  • 用于提升优先级,()优先级为最高 如下,结果是不一样的
System.out.println(3+4*5-6-7+" ");
System.out.println(3+4*(5-6-7)+" ");

  1. 位运算符
  • Java除了具备高级语言的特点外 也支持位运算操作,即二进制位的运算
  • Java中所有的数据都是以二进制形式进行运算的 简言之就是会转换成 010101类的机器代码
  • 如下图就是运算结果
  • 示例
public class TestDemo {
public static void main(String[] args) {
int x = 3;
int y = 6;
System.out.println(x&y);
System.out.println(x|y);
System.out.println(x^y);
}
}

运行结果:
2
7
5

是不是对运行结果一脸懵逼?第一次看是这样的 下面会逐步进行分析

  • 二进制的规律是,由0和1组成,逢2进1 我们平时用的数学就是十进制,逢10进一位 比如 0的二进制就是0 1的二进制就是1 2的二进制就是10 3的二进制就是11 4的二进制就是100 5的二进制就是101 6的二进制就是110
  • 由于Java中整型的长度为32位,所以需要在前面补29个0 如下图 然后我们回到上上张图,位运算结果表 可以看到&与操作的规律是,只有两者都为1,结果才为1,否则都是0 因此,3和6的二进制&操作,很快得到结果是010 恰好等于我们的第一个运行结果2
  • 同样我们再来看另外两个|或操作和^异或操作 然后我们回到上上张图,位运算结果表 可以看到|或操作的规律是,只要有一个为1,则结果为1,否则都是0 可以看到^异或操作的规律是,两者相同则为0,不同则为1 这样就很容易推算出另外两个运行结果为什么是7和5 此外,最左边第一位代表符号位,0代表正数,1代表负数

接着介绍一下~取反

  • 计算机数据表示中只定义了正数的表示形式,并没有定义负数的表示形式,所以负数一般都由补码的形式表示
  • 正数的原码、反码、补码都相同
  • 负数的反码就是除了符号位为1以外,其他位全部取反 负数的补码就是"反码+1"
  • 以给"-3"取反为例
int x = -3;
System.out.println(~x);

运行结果:2

由于负数都是以补码形式存在,而负数的补码则是"反码+1" 那么想得到负数的二进制的步骤可以这样:

「第一步:先得到负数原码,即得到正数二进制,并给符号位设置为1」 正数3的二进制为00......011 那么-3的二进制原码为10......011 「第二步:得到负数反码,即负数原码取反,符号位记得不变」 那么-3的二进制原码为11......100 「第三步:得到负数补码,即负数反码+1,因为负数都是以补码形式存在,这就是我们要的负数最终二进制」 那么-3的二进制补码为11......101

  • 可以看到我们通过上面方法已经得到了-3二进制,且是以补码形式存在 由于最终是要给-x取反~ 那么给每一位取反,最终得到结果2

还有左移<<右移>>操作

  • 左移是将二进制整体向左移动指定位数,之后的空位用0来填充 右移是将二进制整体向右移动指定位数,之后的空位用符号位来填充,若是正则用0,若是负则用1
  • 以"3"为例,左移2位
int x = 3;
System.out.println(x<<2);

运行结果:12

  • 可以看到左移2位后,右边用0补充2位,结果变为1100,即12
  • 再来检验正数"3"右移2位,负数"-3"右移2位
int x = 3;
int y = -3;
System.out.println(x>>2);
System.out.println(y>>2);

运行结果:
0
-1

  • 可以看到 3右移2位,结果全是0,则为0 -3右移2位,结果全是1 即-3右移2位后的二进制为1111...1111
  • 前面讲过负数都是以补码形式存在,而负数的补码则是"反码+1" 那么得到负数的值可以这样:

「第一步:负数补码减一得到负数反码」 1111......1111减一以后得到1111......1110 「第二步:负数反码取反得到负数原码,记得取反不影响符号位」 1111......1110取反后得到1000......00010000......0001代表正数1,二进制第一位代表符号位,很容易得到负数代表的结果是-1,这也是我们的最终运行结果

无符号右移>>>

  • 这个和上面类似,唯一区别是即使是负数,右移后左侧只补0 由于会把负数变为正数,因此也很好算出具体的值
  1. 运算符优先级
  • 这个不过多赘述了
  • 括号()的优先级最高,因此无需死记硬背,实际工作中可以通过括号来改变优先级来适应实际需求

##3.4.2 简洁表达式

  • 表达式是由常量、变量或者其他操作数和运算符组合成的语句 如
-49
sum+2
a+b/d*3-9

  • 还有一些将算术运算符和赋值运算符结合成为新的运算符
  • 就不上示例了,这里应该比较好理解

#3.5 选择与循环语句 ##3.5.1 程序的结构

  • 一般来说程序的结构有顺序、选择和循环 顺序:从上至下,依次执行 选择:根据判断条件决定是否执行,条件成立则执行,不成立则不执行 循环:根据判断条件,决定循环执行的次数 ##3.5.2 选择结构
  1. if
  • 如果括号内判断条件成立,即为true,则执行语句1,否则不执行
if(判断条件){
语句1;
}

  1. if...else
  • 如果括号内判断条件成立,即为true,则执行语句1 否则视为不满足条件,执行语句2
if(判断条件){
语句1;
}else{
语句2;
}

  1. 三目运算符
变量 = 条件判断 ? 表达式1 :表达式2

  • 表示判断条件是否满足,若满足执行表达式1,否则执行表达式2,并将结果返回给变量
  • 示例:找最大值
public class TestDemo {
public static void main(String[] args) {
int max = 0;
int x = 3;
int y = 10;
max = x>y ? x:y;
System.out.println(max);
}
}

运行结果:
10

  1. if...else if...else
  • 多选一的情况,从多种条件中选择符合条件的并执行该语句
public class TestDemo {
public static void main(String[] args) {
int x = 3;
if(x==3){
System.out.println("x的值是3");
}else if(x==2){
System.out.println("x的值是2");
}else if(x==1){
System.out.println("x的值是1");
}else {
System.out.println("x的值是其他值");
}
}
}

运行结果:
x的值是3

  1. switch
  • 多选一,配合break使用,选中后跳出语句
public class TestDemo {
public static void main(String[] args) {
int x = 3;
int y = 6;
char oper = '+';
switch (oper) {
case '+':
System.out.println("x+y=" + (x + y));
break;
case '-':
System.out.println("x+y=" + (x + y));
break;
default:
System.out.println("未知符号");
break;
}
}
}

  • switch先计算括号内的结果,可以是数字、字符和枚举 然后检测是否符合case后的选择值 符合则执行case下的语句,直到遇到break才终止 都不符合则执行default下的语句,直到遇到break才终止
  • switch常和break配合使用 如果case后不加break,则会一直执行其他case下的语句,持续下去,直到遇到break才跳出

##3.5.3 循环结构

  1. while
public class TestDemo {
public static void main(String[] args) {
int x = 1;
int sum = 0;
while (x <= 10) {
sum += x;
x++;
}
System.out.println("1到10累加结果是:" + sum);
}
}

运行结果:
1到10累加结果是:55

  • 先判断括号内条件是否满足,满足则执行花括号内语句 下次会继续判断括号内条件是否满足,若满足则继续循环执行花括号内语句 一般会配合自增运算符,直到变量不满足条件时终止循环

2.do......while

  • 先执行do后面的语句,再判断while条件,并循环 do后面的语句至少执行一次
public class TestDemo {
public static void main(String[] args) {
int x = 1;
int sum = 0;
do {
sum += x;
x++;
}while (x <= 10);
System.out.println("1到10累加结果是:" + sum);
}
}

运行结果:
1到10累加结果是:55

3.for循环for循环嵌套

public class TestDemo {
public static void main(String[] args) {
int sum = 0;
for (int x=1; x<=10;x++){
sum += x;
}
System.out.println("1到10累加结果是:" + sum);
}
}

运行结果:
1到10累加结果是:55

  • 第一次进入for循环,先给循环控制变量赋初值 根据判断条件检查是否要继续执行循环 当条件判断为true时执行循环主体内的语句 为false则跳出循环 执行完循环主体内的语句后,环控制变量一般会执行自增操作 然后继续重新回到判断条件语句,检查是否执行循环
public class TestDemo {
public static void main(String[] args) {
for (int i=1; i<=3;i++){
for (int j=1; j<=i;j++){
System.out.print(i+"-"+j);
}
System.out.print(“\n”);
}
}
}

运行结果:
1-1
2-1 2-2
3-1 3-2 3-3

  • 嵌套for由外到内,需要注意循环的次数 如示例 首先当i=1的时候,执行完里面j的for内循环 接着i++,此时i=2,又继续执行一遍内部j的循环 直到i不满足i<=3则停止整个循环

##3.5.4 循环的中断

  1. break
  • 退出当前最近的整个循环
public class TestDemo {
public static void main(String[] args) {
for (int i=0; i<10;i++){
if(i==3){
break;
}
System.out.println(i+"");
}
}
}

运行结果:
0
1
2

  1. continue
  • 退出本次循环,继续下一次循环
public class TestDemo {
public static void main(String[] args) {
for (int i=0; i<10;i++){
if(i==3){
continue;
}
System.out.println(i+"");
}
}
}

运行结果:
0
1
2
4
5
...

提一下局部变量

  • 循环语句中定义的变量属于局部变量 有效范围是在循环语句中,而在循环语句外无法使用 如上例的 i就是局部变量

本文使用 mdnice 排版

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值