2. 基础语法
1. 注释
1、java中注释分为三种:注释不会被编译成字节码文件
(1)、单行注释: // 只能注释一行代码。如://类成员变量
(2)、多行注释: /*注释内容*/ 可注释多行代码,其中不允许出现嵌套。
(3)、文档注释: /** */ 使用文档注释,当导出doc文件的时候会一起导出来
建议:声明多个相同类型变量时要分行声明,有利于提高代码。
2、如何将项目中的接口方法导出?
右击选择export--》javadoc-->finish
3、注释
注释就是程序员为读者作的说明,是提高程序可读性的一种手段
(1)、在Java中,有2种表示注释的方法
// 单行注释----注释内容从//到本行结尾
/*
单行或多行注释
*/
/* */注释不能嵌套
(2)、Java中的注释不会出现在字节码文件中。即JAVA编译器编译时会跳过注释语句。
public class Welcome {
//我是单行注释
public static void main(String[] args/*我是行内注释 */) {
System.out.println("Hello World!");
}
/*
我是多行注释!
我是多行注释!
*/
}
A=65 a=97 0=48 空格=32
2. 标识符
1、标识符:给变量,常量,方法,类和包起的名称
2、需要遵循的规范:(必须遵守)
(1)、首字母必须是字母,下划线,或者$ 如:Man, GoodMan
(2)、其余部分可以是字母,下划线,$或者数字
(3)、java严格区分大小写,并且长度无限制
(4)、表示方法和变量的标识符用小写字母开始,后面的描述性词以大写开始。eat(),eatFood()
(5)、禁止使用java中的保留字(关键字)
(6)、可以使用汉字命名,但是不建议
(7)、需要遵守的准则:不遵守程序不会报错,但是不规范(道德约束)
(8)、驼峰标识:一个名称由多个单词组成,每个组成的单词必须首字母大写,其余部分小写(给方法,变量起名字的时候第一个字母也小写)
(9)、见名知意:看到名称即知道是什么意思
3、JAVA不采用通常语言使用的ASCII字符集,而是采用unicode这样的标准的国际字符集。因此,这里的字母的含义:英文、汉字等等。(不建议大家使用汉字来定义标识符!),ascll占用1个字节,占8位,一共128个字符,记住48‘0’,65‘A’,97 'a'
4、各种字符集的关系?
(1)、合法的标识符:
int a = 3;
int _123 = 3;
int $12aa = 3;
int 变量1 = 55;
(2)、不合法的标识符:
int 1a = 3; //不能用数字开头
int a# = 3; //不能包含#这样的特殊字符
int int = 3; //不能使用关键字
3. 关键字/保留字
关键字/保留字
Java关键字是Java语言保留供内部使用的,如class用于定义类。 关键字也可以称为保留字,它们的意思是一样的。
不能使用关键字作为变量名或方法名。
abstract | Assert | boolean | break | byte | case |
catch | char | class | const | continue | default |
do | Double | else | extends | final | finally |
float | For | goto | if | implements | import |
instanceof | Int | interface | long | native | new |
null | Package | private | protected | public | return |
short | Static | strictfp | super | switch | synchronized |
this | Throw | throws | transient | try | void |
volatile | While |
|
|
|
|
4. 变量和常量
1、变量(variable)
在程序运行过程中,值发生变化,我们通过变量来操纵存储空间中的数据,变量就是指代这个存储空间!空间位置是确定的,但是里面放置什么值不确定!
2、Java是一种强类型语言,每个变量都必须声明其类型。
(1)、Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
(2)、变量在使用前必须对其声明, 只有在变量声明以后,才能为其分配相应长度的存储单元,声明格式为:
(3)、type varName [=value] [{,varName[=value]}] ;
(4)、注意事项:
(5)、每个变量都有类型,类型可以是基本类型,也可以是引用类型。
(6)、变量名必须是合法的标识符。
3、变量如何定义?
声明加赋值或者先声明,后赋值。变量声明是一条完整的语句,因此每一个声明都必须以分号结束。
(1)变量声明举例:
double salary ; boolean done;
long earthPopulation ; int age ;
(2)可以在一行中声明多个变量:
int i ,j; // both are integers
不提倡这种风格,逐一声明每一个变量可以提高程序可读性。
(3)可以将变量的声明和初始化放在同一行中,例如:
int age = 18; float e = 2.718281828f;
4、变量可划分为:
(1)局部变量(lacal variable):定义在方法内的变量,作用域:声明位置开始到整个方法结束
局部变量在定义的时候必须赋初值,不赋初始值会报错,该方法调用结束后,则会释放方法中的局部变量占用的内存空间,即销毁。
在使用前必须先声明和初始化(赋初值)。
public void incorrectLocalV() {
int i;
i=10;
int j = i+5 ; // 编译出错,变量i还未被初始化
}
(2)成员变量(member variable):方法外部、类的内部定义的变量。作用域:整个类体有效,从属于对象,生命周期伴随对象始终。成员变量又可以分为静态变量(static int i=5)和实例变量(int k=6);
成员变量在定义的时候可以不赋初值,,他会自动初始化成该类型的默认初始值(数值型变量初始化成0或0.0,字符型变量的初始化值是16位的0,布尔型默认是false)。
(3)静态变量(类变量 static variable):使用static定义。 作用域:有效范围可以跨类,从属于类,生命周期伴随类始终,从类加载到卸载。 除了能在定义它的类内存中取值,还可以直接以“类名.静态变量”的方式在其他类内使用。
注:局部变量与静态变量名字相同时,此时成员变量将被隐藏。即这个静态变量在此方法中暂时失效。如果想调用成员变量,需要使用“类名.静态变量”
练习1:
public class LocalVariableTest {
public static void main(String[ ] arg) {
boolean flag = true; // 声明boolean型变量并赋值
char c1, c2; // 声明char型变量
c1 = '\u0041'; // 为char型变量赋值
c2 = 'B'; // 为char型变量赋值
int x; // 声明int型变量
x = 9; //为int型变量赋值
int y = x; // 声明并初始化int型变量
float f = 3.15f; // 声明float型变量并赋值
double d = 3.1415926; //声明double型变量并赋值
}
}
5、常量(Constant):
(1)初始化(initialize)后不能再改变值!
(2)在程序运行过程中,值不会发生变化的量,只进行一次赋值,叫做常量
(3)常量一般使用final进行修饰,值被对象共享
补充:在进行常量声明定义的时候,一般取名全部大写并且用 _ 隔开,但是是不必须的,只是为了让符合命名规范。如果常量属于成员变量,必须在定义时并赋初值。
public class Constants {
public static void main(String[] args) {
final double PI = 3.14;
// PI = 3.15; //error
double r = 4;
double area = PI * r * r;
double circle = 2 * PI * r;
System.out.println("area = " + area);
System.out.println("circle = " + circle);
}
}
6、命名规则(规范)
(1)所有变量、方法、类名:见名知意
(2)类成员变量:首字母小写和驼峰原则 : monthSalary
(3)局部变量:首字母小写和驼峰原则
(4)常量:大写字母和下划线:MAX_VALUE
(5)类名:首字母大写和驼峰原则: Man, GoodMan
(6)方法名:首字母小写和驼峰原则: run(), runRun()
7、变量内存分析
(1)定义成员变量
int count = 10;
//在方法执行的时候,会先从栈中找变量,如果栈中没有对应的值,则再从堆中寻找变量值
public void show(int count){
//就近原则:距离谁近,就输出谁
System.out.println(count);
count = 100;
System.out.println(count);
System.out.println(this.count);
}
public void show2(){
System.out.println(count);
int count = 20;
System.out.println(count);
}
public static void main(String[] args) {
VariableDemo vd = new VariableDemo();
vd.show(50);//50-->100-->10
vd.show2();//10-->20
}
(2) Point p1 = new Point();
p1.x = 3;
p1.y = 4;
// 设置x,y的坐标
// p1.setX(5);
// p1.setY(6);
Point p2 = new Point(6, 8);
p1.show();
p2.show();
System.out.println(p1.calaDistance(p2.x, p2.y));
System.out.println(p1.calaDistance(p2));
p1.swap(p1.x, p1.y);
p1.show();
p1.swap();
p1.show();
(3)// 创建对象
Adminstrator admin1 = new Adminstrator();
// 给对象赋值
admin1.username = "admin1";
admin1.password = "111111";
Adminstrator admin2 = new Adminstrator();
admin2.username = "admin2";
admin2.password = "222222";
admin1.show();
admin2.show();
System.out.println(admin1.toString());
System.out.println(admin2);
用户名是:admin1,密码:111111
用户名是:admin2,密码:222222
five.Adminstrator@2e6c01b9
five.Adminstrator@34e5307e
5. 基本数据类型
1、基本数据类型(primitive data type)
(1)Java是一种强类型语言,每个变量都必须声明其类型。
(2)Java的数据类型分为两大类:基本类型(primitive type)和引用类型(reference type)
(3)Java中定义了4类8种基本数据类型
逻辑型-boolean 文本型- char
数值型- byte, short, int, long, float, double
注:引用数据类型的大小统一为4个字节,记录的是其引用对象的地址!
2、整型变量
(1)整型用于表示没有小数部分的数值,它允许是负数。
(2)整型的范围与运行Java代码的机器无关,这正是Java程序具有很强移植能力的原因之一。
(3)类型 占用存储空间 表数范围
Byte 1字节 -128~127
Short 2字节 -215 ~ 215-1 (-32768~32767)
Int 4字节 -231 ~ 231-1 (2147483648~2147483647) 约21亿
Long 8字节 -263 ~ 263-1
(4)Java 语言整型常数的三种表示形式:
十进制整数,0-9 如:99, -500, 0。
八进制整数,要求以 0 开头,如:015。
十六进制数,要求 0x 或 0X 开头,如:0x15 。
正常情况下,使用十进制表示一个数,但是在计算机中,还可以使用其他进制表示数
3、进制之间的转换
(1)、十进制转二进制:将十进制数依次除以2,并保留余数,当除完为0的时候,将余数逆序输出即为二进制的表示
(2)、二进制转十进制:将二进制的每位依次乘以对应位数的次幂,然后想加即为十进制数
(3)、十进制转十六进制:将十进制数依次除以16,并保留余数,当除完为0的时候,将余数逆序输出
将十进制首先转为二进制数,从右向左,四位组成一组,每组转成一个16进制数即可
(4)、十六进制十进制:将十六进制的每位依次乘以对应位数的次幂,然后想加即为十进制数
(5)、将十六进制转为二进制:每一位十六进制数换为4位二进制表示即可
(6)、将二进制转为十六进制:将4位二进制数组成一组,转成十六进制即可
4、Java语言的整型常数默认为int型,声明long型常量可以后加‘ l ’或‘ L ’ ,如:
long a = 55555555; //不出错,在Int表示的范围内(21亿内)。
long b = 55555555555;//不加l出错,已经超过int表示的范围。报错:
5、Java中没有无符号类型,浮点型
类型 占用存储空间 表数范围
Float 4字节 -3.403E38~3.403E38
Double 8字节 -1.798E308~1.798E308
(1)float类型又被称作单精度类型,尾数可以精确到7位有效数字,在很多情况下,float类型的精度很难满足需求。
(2)double表示这种类型的数值精度是float类型的两倍,又被称作双精度,绝大部分应用程序都采用double类型。
(3)Java 浮点类型常量有两种表示形式
十进制数形式,例如:3.14 314.0 0.314
科学记数法形式,如:314e2 314E2 314E-2
double f = 314e2; //314*10^2-->31400.0
double f2 = 314e-2; //314*10^(-2)-->3.14
(4)Float类型的数值有一个后缀F/f ,没有后缀F/f的浮点数值默认为double类型。也可以在浮点数值后添加后缀D/d, 以明确其为double类型:
(5)浮点类型float, double的数据不适合在不容许舍入误差的金融计算领域。如果需要进行不产生舍入误差的精确数字计算,需要使用BigDecimal类。
主要理由:由于字长有限,浮点数能够精确表示的数是有限的,因而也是离散的。浮点数一般都存在舍入误差,很多数字无法精确表示(例如0.1),其结果只能是接近,但不等于。
(6)二进制浮点数不能精确的表示0.1,0.01,0.001这样10的负次幂。并不是所有的小数都能可以精确的用二进制浮点数表示。
最好完全避免使用浮点数比较:
(7)大数值:
Java.math下面的两个有用的类:BigInteger和BigDecimal,这两个类可以处理任意长度的数值。BigInteger实现了任意精度的整数运算。BigDecimal实现了任意精度的浮点运算。
(8)浮点数使用总结:
默认是double
浮点数存在舍入误差,很多数字不能精确表示。如果需要进行不产生舍入误差的精确数字计算,需要使用BigDecimal类。
避免比较中使用浮点数
6、字符型(2个字节)
(1)单引号用来表示字符常量。例如‘A’是一个字符,它与“A”是不同的,“A”表示含有一个字符的字符串。
(2)char 类型用来表示在Unicode编码表中的字符。
(3)Unicode编码被设计用来处理各种语言的所有文字,它占2个字节,可允许有65536个字符;ASCII码占1个字节,可允许有128个字符,是Unicode编码表中前128个字符。
char eChar = 'a';
char cChar ='中';
(4)Unicode具有从0到65535之间的编码,他们通常用从’\u0000’到’\uFFFF’之间的十六进制值来表示(前缀为u表示Unicode)
char c = ‘\u0061;
(5)Java 语言中还允许使用转义字符 ‘\’ 来将其后的字符转变为其它的含义,
char c2 = '\n'; //代表换行符
(6)转义符 含义 Unicode值
\b 退格(backspace) \u0008
\n 换行 \u000a
\r 回车 \u000d
\t 制表符(tab) \u0009
\“ 双引号 \u0022
\‘ 单引号 \u0027
\\ 反斜杠 \u005c
注:以后我们学的String类,其实是字符序列(char sequence)。
5、boolean类型(一位,不是一个字节):
(1)boolean类型有两个值,true和false,不可以 0 或非 0 的整数替代 true 和 false ,这点和C语言不同。
(2)boolean 类型用来判断逻辑条件,一般用于程序流程控制 。
boolean flag ;
flag = ………;
if(flag) {
// true分支
} else {
// false分支
}
(3)实践:Less is More!!请不要这样写:if ( is == true && done == false ) ,只有新手才那么写。对于任何程序员 if ( whether && !done ) 都不难理解吧。所以去掉所有的==fasle 和 ==true。
6. 运算符
1、运算符(operator)
Java 语言支持如下运算符:
(1)算术运算符: +,-,*,/,%,++,--
(2)赋值运算符 =
(3)关系运算符: >,<,>=,<=,==,!= instanceof
(4)逻辑运算符: &&,||,!
(5)位运算符: &,|,^,~ , >>,<<,>>> (了解!!!)
(6)条件运算符 ?:
(7)扩展赋值运算符:+=,-=,*=,/=
2、一元运算符(++, --)
int a = 3;
int b = a++; //执行完后,b=3。先给b赋值,再自增。
int c = ++a; //执行完后,c=5。先自增,再给b赋值
注意:java中的乘幂处理:
int a = 3^2; //java中不能这么处理, ^是异或符号。
double b = Math.pow(3, 2);
单目运算符,表示自增1或者自减1,谁在前,就先运算谁;
3、二元运算符
(1)整数运算:
如果两个操作数有一个为Long, 则结果也为long
没有long时,结果为int。即使操作数全为shot,byte,结果也是int.
(2)浮点运算:
如果两个操作数有一个为double, 则结果为double.
只有两个操作数都是float, 则结果才为float.
(3)取模运算:
其操作数可以为浮点数,一般使用整数。如:5.9%3.9=2.000000004
(4)要点:
负数%负数=负数;
负数%正数=负数;
正数%负数=正数;
注:一般都是正整数运算,不用考虑这么细!
4、布尔逻辑表达符
(1)逻辑与:&&和&,逻辑或:||和|,逻辑非:!。
(2)逻辑与和逻辑或采用短路的方式。从左到右计算,如果确定值则不会再计算下去。
(3)逻辑与只要有一个为false, 则直接返回false.
(4)逻辑或只要有一个为true, 则直接返回true;
注:!取反;&& 短路与:当表达式左边为false的时候,不需要关心右边是什么结果;|| 短路或:当表达式左边为true的时候,不需要关心右边是什么结果;建议使用短路与短路或
boolean c = 1>2&&2>(3/0);
5、位运算符
当进行位运算的时候,需要把数转为对应的二进制
(1)~ -- 取反 & -- 按位与
(2)| -- 按位或 ^ -- 按位异或
(3)<<:左移运算符, >>:右移运算符 >>>:无符号移位运算符
(4)按位与 &(两个操作数都为1才为1,否则为0)
(5)按位或 | (两个操作数都为0才为0,否则为1)
(6)按位非~ (二进制数中有1全部改为0,0全部改为1)
(7)按位异或^(两个操作数相异为1,相同为0)
(8)<<左移:左移一位相当于乘2。
(9)>> 右移:右移一位相当于除2取商。(说明,最高位是0,左移空的位就填入0,如果最高位是1,左移空的位就填入1)
(10)>>>无符号右移(不管最高位是0还是1,最高位都填入0)
int a = 3*2*2;
int b = 3<<2; //相当于:3*2*2; 数 <<移动几位
int a = 12/2/2;
int b = 12>>2;
6、扩展运算符
运算符 用法举例 等效的表达式
+= a += b a = a+b
-= a -= b a = a-b
*= a *= b a = a*b
/= a /= b a = a/b
%= a %= b a = a%b
7、字符串连接符
“+”运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串然后再进行连接。
int c = 12;
System.out.println("c=" + c);
8、三目条件运算符
(1)三目条件运算符,语法格式:x ? y : z
其中 x 为 boolean 类型表达式,先计算 x 的值,若为true,则整个三目运算的结果为表达式 y 的值,否则整个运算结果为表达式 z 的值。
举例:
int score = 80; int x = -100;
String type = score < 60 ? "不及格" : "及格";
int flag = x > 0 ? 1 : (x == 0 ? 0 : -1);
System.out.println("type= " + type);
System.out.println("flag= "+ flag);
9、运算符符优先级:增量和减量运算 > 算数运算 > 比较运算 > 逻辑运算 > 赋值运算(简记:自算比逻赋)
10、自动类型转换:
(1)自动类型转换:容量小的数据类型可以自动转换为容量大的数据类型。在图中,黑色的实线表示无数据丢失的自动类型转换,而红色的虚线表示在转换时可能会精度的损失。
(2)特例: 可以将整型常量直接赋值给byte, short, char等类型变量,而不需要进行强制类型转换,只要不超出其表数范围。
Short b = 12; //合法
short b = 1234567; //非法
short sh = 1; sh = sh + 1; //报错:在进行运算的时候会进行类型转换,运算完成的数值是int型,无法直接赋值给short;如果是 sh+=1,正常运行。
(3)强制类型转换(Cast): 强制类型转换,又被称为造型,用于显式的转换一个数值的类型. 在有可能丢失信息的情况下进行的转换是通过造型来完成的,但可能造成精度降低或溢出。
(4)强制类型转换的语法格式:“(type)var”,运算符“()”中的type表示将值var想要转换成的目标数据类型。
例如:double x = 3.14;
int nx = (int)x; //值为3
char c = 'a';
int d = c+1;
System.out.println(d);
System.out.println((char)d);
(5)当将一种类型强制转换成另一种类型,而又超出了目标类型的表示范围,就会被截断成为一个完全不同的值。
例如: int x = 300;
byte bx = (byte)x; //值为44
(6)不能在布尔类型和任何数值类型之间做强制类型转换。
11、基本类型转化时常见错误和问题
(1)操作比较大的数时,要留意是否溢出,尤其是整数操作时。
int money = 1000000000; //10亿
int years = 20;
int total = money*years; //返回的是负数
long total1 = money*years; //返回的仍然是负数。默认是int,因此结果会转成int值,再转成long。但是已经发生了数据丢失
long total2 = money*((long)years); //先将一个因子变成long,整个表达式发生提升。全部用long来计算
(2)L和l 的问题:不要命名名字为l的变量,long类型使用大写L不要用小写。
int l = 2;
long a = 23451l;
System.out.println(l+1);
12、注意:
(1)在java中,除法是整除; %取模运算,取余数;
(2)关系运算符 > < >= <= != == ,返回的类型是boolean,用于做逻辑判断
(3)除了八大基本类型数组有各自的默认类型, 其余的自定义数组的默认值都是 null.
(4)int型变量:7 的二逃制表示是 00000000 00000000 00000000 00000111。
-8 的二进制表示是11111111 11111111 11111111 11110000.
0代表正数,1代表负数。
7. 方法
方法
(1)Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,声明格式:
[修饰符1 修饰符2 …] 返回值类型 方法名(形式参数列表){
Java语句;… … …
}
形式参数:在方法被调用时用于接收外界输入的数据。
实参:调用方法时实际传给方法的数据。
返回值:方法在执行完毕后返还给调用它的环境的数据。
返回值类型:事先约定的返回值的数据类型,如无返回值,必须给出返回值类型void。
Java语言中使用下述形式调用方法:对象名.方法名(实参列表)
实参的数目、数据类型和次序必须和所调用方法声明的形参列表匹配,
return 语句终止方法的运行并指定要返回的数据。
Java中进行方法调用中传递参数时,遵循值传递的原则:
基本类型传递的是该数据值本身。引用类型传递的是对对象的引用,而不是对象本身。
JAVA中只有值传递!
8. 简单的键盘输入和输出
简单的键盘输入和输出
简单的读取键盘输入的字符串示例: Scanner scanner = new Scanner(System.in); // String string = scanner.nextLine(); //将输入的一行付给string // String string = scanner.next(); //将输入单词到第一个空白符为止的字符串付给string int string = scanner.nextInt(); //将输入的数字付给变量 System.out.println(string);
|
装饰者模式(java设计模式的一种)
Scanner scanner = new Scanner(System.in);
System.in表示标准输入流,从控制台读取数据
Scanner scanner = new Scanner(new File("d:\\aaa.txt"));
从文本文件中读取数据
使用Scanner 输入结束之后记得用 scanner.close( )关闭资源
9. 流程控制结构
1、流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。其流程控制方式采用结构化程序设计中规定的三种基本流程结构,即:顺序结构、分支结构和循环结构,如下图所示:
2、顺序结构
JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行顺序结构是最简单的算法结构,语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构。顺序结构在程序流程图中的体现就是用流程线将程序框自上而地连接起来,按顺序执行算法步骤。
3、选择结构
(1)if单选择结构
如果条件为true执行一个操作:
意义:if语句对条件表达式进行一次测试,若测试为真,则执行下面的语句,否则跳过该语句
double i = 6 * Math.random();
double j = 6 * Math.random();
double k = 6 * Math.random();
int count = (int) (i + j + k);
if(count > 15) {
System.out.println("今天手气不错");
}
if(count >= 10 && count <= 15) { //错误写法:10<count<15
System.out.println("今天手气很一般");
}
if(count < 10) {
System.out.println("今天手气不怎么样");
}
System.out.println("得了" + count + "分");
Math类的使用:
int i = (int) (6 * Math.random()); //产生:[0,5]
(2)if-else双选择结构:
如果条件为true执行一个操作,为false执行另一个操作:
意义:当条件表达式为真时,执行语句块1,否则,执行语句块2。也就是else部分。
double r = 4 * Math.random();
double area = Math.PI * Math.pow(r, 2);
double circle = 2 * Math.PI * r;
System.out.println("半径为: " + r);
System.out.println("面积为: " + area);
System.out.println("周长为: " + circle);
if(area >= circle) {
System.out.println("面积大于等于周长");
} else {
System.out.println("周长大于面积");
}
(3)If-elseif-else多选择结构
if(布尔表达式1) {
语句块1;
} else if(布尔表达式2) {
语句块2;
}………
else if(布尔表达式n){
语句块n;
} else {
语句块n+1;
}
逐条if语句进行判断,条件匹配,进入语句体,否则对if语句继续匹配
public class IfTest3 {
public static void main(String[] args) {
int age = (int) (100 * Math.random());
System.out.print("年龄是" + age + ", 属于");
if (age < 15) {
System.out.println("儿童, 喜欢玩!");
} else if (age < 25) {
System.out.println("青年, 要学习!");
} else if (age < 45) {
System.out.println("中年, 要工作!");
} else if (age < 65) {
System.out.println("中老年, 要补钙!");
} else if (age < 85) {
System.out.println("老年, 多运动!");
} else {
System.out.println("老寿星, 古来稀!");
}
}
}
(4)switch多选择结构
根据表达式值的不同执行许多不同的操作
Switch语句:case标签必须是整数或者枚举,不能是字符串。根据表达式的值,从一系列代码选出一段执行。格式如下:
switch (表达式) {
case 值1:
语句序列;
[break];
case 值2:
语句序列;
[break];
… … … … …
[default:
默认语句;]
}
switch语句会根据表达式的值从相匹配的case标签处开始执行,一直执行到break语句处或者是switch语句的末尾。与任一case值不匹配,则进入default语句(如果有的话)
public class VowelsAndConsonants {
public static void main(String[] args) {
char c = 'a';
int rand =(int) (26*Math.random());
char c2 = (char)(c+rand);
System.out.print(c2 + ": ");
switch (c2) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
System.out.println("元音"); break;
case 'y':
case 'w':
System.out.println("半元音"); break;
default:
System.out.println("辅音");
}
}
}
提示: switch一般用来做多值的判断,如果为条件为区间则最好使用ifelse来做。当然,也可以通过某些计算将区间变通为多值的判断。(了解!!!)
int score =(int)(Math.random()*100);
if(score>=0&&score<=100){
switch (score/10) {
case 10:
case 9:
System.out.println("成绩优秀!");
break;
case 8:
System.out.println("成绩良好!");
break;
case 7:
System.out.println("成绩一般!");
break;
case 6:
System.out.println("成绩合格!");
break;
default:
System.out.println("不及格,寻访名师指点!");
}
}else{
System.out.printf
(5)条件运算符有时候可用于代替if/else:
int a=2; int b=3;
if (a<b) {
System.out.println(a);
} else {
System.out.println(b);
}
与下面代码效果相同:
int a=2; int b=3;
System.out.println((a<b)?a:b);
建议以后使用三目条件判断
10. 循环结构
循环结构都由如下四个结构组成: 初始化、条件判断、循环体
1、While循环
while语句格式
while (布尔表达式) {
循环体;
}
(1)在循环刚开始时,会计算一次“布尔表达式”的值,若条件为真,执行循环体。而对于后来每一次额外的循环,都会在开始前重新计算一次。
(2)语句中应有使循环趋向于结束的语句,否则会出现无限循环–––"死"循环。while(true){ }无限循环
举例:
public class WhileTest {
public static void main(String[] args) {
int i = 0;
int sum = 0;
while (i <= 100) { // 1+2+3+…+100=?
sum += i; //sum = sum+i;
i++;
}
System.out.println("Sum= " + sum);
}
}
2、Do-while循环 (“直到型” 循环):
while 语句为如下形式
do {
循环体;
} while(布尔表达式) ;
先执行循环体,后判断布尔表达式,循环体至少执行一次
public class Test {
public static void main(String[] args) {
int i = 0;
int sum = 0;
do {
sum += i; // sum = sum + i
i++;
} while (i <= 100);
System.out.println("Sum= " + sum);
}
}
3、While和do while的区别
Do while总是保证循环体会被至少执行一次!这是他们的主要差别
int a = 0;
while(a<0){
System.out.println(a);
a++;
}
System.out.println("-----");
a=0;
do{
System.out.println(a);
a++;
} while (a<0);
执行结果:
-----
0
4、For循环
(1)for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构
(2)语法形式
for (初始表达式;布尔表达式;步进) {
循环体;
}
(3)for循环在第一次反复之前要进行初始化。随后,它会进行条件测试,而且在每一次反复的时候,进行某种形式的“步进”。
1)初始化部分设置循环变量的初值
2)条件判断部分为任意布尔表达式
3)迭代因子控制循环变量的增减
(4)for循环在执行条件测试后,先执行程序部分,再执行步进。
for (初始表达式;布尔表达式;迭代因子) {
循环体;
}
public class ForTest {
public static void main(String args[]) {
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
System.out.println("Sum= " + sum);
for(int i=9;i>0;i--){
System.out.println(i);
}
for(int i=90;i>0;i-=3){
System.out.println(i);
}
}
}
(5)(了解!!!)Java里唯一用到逗号运算符的地方就是for循环的控制表达式。在控制表达式的初始化和步进控制部分,我们可以使用一系列由逗号分隔的表达式。而且那些表达式均会独立执行。例如:
public static void main(String[] args) {
for(int i = 1, j = i + 10; i < 5; i++, j = i * 2) {
System.out.println("i= " + i + " j= " + j);
}
1)无论在初始化还是在步进部分,语句都是顺序执行的。
2)尽管初始化部分可设置任意数量的定义,但都属于同一类型。
3)约定:只在for语句的控制表达式中写入进行初始化,测试和修改同一计数器变量的表达式。
4)初始化部分、条件判断部分和迭代因子可以为空语句,但以“;”分开,下面的语句表示无限循环
for ( ; ; ) { // infinite loop while(true)
...
}
5)在for语句的初始化部分声明的变量,其作用域为整个for循环体,例如:
for(int i = 1; i < 10; i++) {
……
}// i no longer defined here
(6)嵌套循环: 指的是在一个循环语句内部再嵌套一循环或多个循环。
应用举例
public class LoopForTest {
public static void main(String args[]) {
for (int i=1; i <=5; i++) {
for(int j=1; j<=5; j++){
System.out.print(i+" ");
}
}
}
}
5、break语句和continue语句
(1)在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句
(break语句还可用于多支语句switch中)
public class BreakTest {
public static void main(String[] args) {
int total = 0;
System.out.println("Begin");
while(true) {
total++;
int i = (int)Math.round(100 * Math.random());
if(i == 88) break;
}
System.out.println("Game over, used " + total + " times.");
}
}
(2)无限循环的第二种形式是for(;;)。编译器将while(true)与for(;;)看作同一回事。
(3)continue 语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
(4)用在while,do-while中,continue 语句立刻跳到循环首部,越过了当前循环的其余部分。
(5)用在for循环中,跳到for循环的迭代因子部分。
把100~150之间不能被3整除的数输出:
public class ContinueTest {
public static void main(String[] args) {
for (int i = 100; i < 150; i++) {
if (i % 3 == 0)
continue;
System.out.println(i);
}
}
}
(6)带标签的break&continue:(了解!!!)
goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的一个保留字,但并未在语言中得到正式使用;Java没有goto。然而,在break和continue这两个关键字的身上,我们仍然能看出一些goto的影子---带标签的break和continue。
“标签”是指后面跟一个冒号的标识符,例如:label:
(7)对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。例如:
label1:外部循环{
内部循环{
//...
break;
//...
continue;
//...
continue label1;
//...
break label1;
}
}
带标签的break和continue的例子:
public class PrimeNumber { //打印101-150之间所有的质数
public static void main(String args[]) {
int count = 0;
outer: for (int i = 101; i < 150; i ++) {
for (int j = 2; j < i / 2; j++) {
if (i % j == 0)
continue outer;
}
System.out.print(i+ " ");
}
}
}
在Java里唯一需要用到标签的地方就是拥有嵌套循环,而且想中断或继续多个嵌套级别的时候。 在Dijkstra的“Goto有害”论中,他最反对的就是标签,而非goto。随着标签在一个程序里数量的增多,他发现产生错误的机会也越来越多。标签和goto使我们难于对程序作静态分析。这是由于它们在程序的执行流程中引入了许多“怪圈”。但幸运的是,Java标签不会造成这方面的问题,因为它们的活动场所已被限死,不可通过特别的方式到处传递程序的控制权。由此也引出了一个有趣的问题:通过限制语句的能力,反而能使一项语言特性更加有用。
11. 递归结构
1、什么是递归(recursion)?
(1)程序调用自身的编程技巧称为递归。
(2)一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法
2、递归问题的特点是什么?
a、一个问题可被分解为若干层简单的子问题
b、子问题和其上层问题的解决方案一致
c、外层问题的解决依赖于子问题的解决
3、递归结构包括哪两个部分?
a、递归结束条件。解答:什么时候不调用自身方法。如果没有条件,将陷入死循环。
b、递归体。解答:什么时候需要调用自身方法。
4、递归优缺点?
a、递归的优点 :简单的程序
b、递归的缺点 :递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环慢的多
5、递归的使用场合是什么?
a、任何可用递归解决的问题也能使用迭代解决。
b、当递归方法可以更加自然地反映问题,并且易于理解和调试,并且不强调效率问题时,可以采用递归;
c、在要求高性能的情况下尽量避免使用递归,递归既花时间又耗内存。
典型事例:计算n!:
public class A {
static long factorial(int n){
if(n==1){
return 1;
}else{
return n*factorial(n-1);
}
}
public static void main(String[] args) {
long d1 = System.currentTimeMillis();
System.out.printf("%d阶乘的结果:%s%n",10,factorial(10));
long d2 = System.currentTimeMillis();
System.out.printf("递归费时:%s%n",d2-d1); //耗时:32ms
}
}
12. package
1、package
(1)为什么需要package?
为了解决类之间的重名问题。
为了便于管理类:合适的类位于合适的包!
(2)package怎么用?
通常是类的第一句非注释性语句。
包名:域名倒着写即可,再加上模块名,并与内部管理类。
其实内部实现就是靠目录结构来做到的。
com.sun.test
com.oracle.test
com.csy.gao.view.model
(3)注意事项:
写项目时都要加包,不要使用默认包。com.gao和com.gao.car,这两个包没有包含关系,是两个完全独立的包。只是逻辑上看起来后者是前者的一部分。
2、JDK中的主要包
(1)java.lang-包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。
(2)java.awt-包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。
(3)java.net-包含执行与网络相关的操作的类。
(4)java.io-包含能提供多种输入/输出功能的类。
(5)java.util-包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。
4、import
(1)为什么需要import?
如果不适用import,我们如果用到其他包的类时,只能这么写:java.util.Date,代码量太大,不利于编写和维护。通过import可以导入其他包下面的类,从而可以在本类中直接通过类名来调用。
(2)import怎么使用?
import java.util.Date;
import java.util.*; //导入该包下所有的类。会降低编译速度,但不会降低运行速度。
(3)注意要点:
java会默认导入java.lang包下所有的类,因此这些类我们可以直接使用。
如果导入两个同名的类,只能用包名+类名来显示调用相关类:
(4)java.util.Date date = new java.util.Date();
(5)static import静态导入(JDK 1.5后增加, 了解!!!!):
静态导入的作用:用于导入指定类的静态属性
如何使用:
import static java.lang.Math.*;//导入Math类的所有静态属性
import static java.lang.Math.PI;//导入Math类的PI属性
然后,我们可以在程序中直接使用:System.out.println(PI);
上面两种导入方式都是为了便于编写代码,提高可维护性。
13. 语句块
1、块(有时叫做复合语句),是用花括号扩起的任意数量的简单java语句。块确定了局部变量的作用域。
块中的程序代码,作为一个整体,是要被一起执行的。
块可以被嵌套在另一个块呢。
不能在两个嵌套的块内声明同名的变量。语句块可以使用外部的变量!语句块中定义的变量作用域只限于语句块。
public static void main(String[] args) {
int n;
int a;
{
int k;
int n; //error – can’t redefine n in inner block
}//k is only defined up to here
}