4 基础
4.1 注释
comments
书写注释是非常好的习惯
Java中有三种注释
- 单行注释
- 多行注释
- 文档注释
文档注释
/**
* @Author lee
*/
4.2 标识符
- 类名,变量名,方法名都被称为标识符
- 标识符以字母,美元符,下划线开始
- 不能使用关键字作为方法名或者变量名...
- 大小写敏感
- 可以使用中文作为变量名,但不建议
4.3 关键字
事先定义的,有特别意义的标识符,有时又叫保留字
String 不是关键字,String是一个类
4.4 数据类型
强类型语言
要求变量的使用严格符合规范,所有变量先定义再使用
弱类型语言
没那么严格的要求,不必事先声明,变量的类型也可能会变化
Java数据类型分为两大类:基本类型和引用类型
基本类型
primitive type
- 数值类型
- 整数类型 byte 1,short 2,int 4,long 8 [字节]
- 浮点类型 float 4,double 8 [字节]
- 字符类型 char 2 [字节]
- 布尔类型 boolean 1 [位]
注意事项:
long num = 30L //之后要加L 一般用大写以免混淆
float n = 50.1F //之后要加F
拓展
整数拓展
- 二进制 0b
- 八进制 0
- 十进制
- 十六进制 0x
浮点数拓展
//银行面试题 业务里的钱怎么表示?
//使用BigDecimal 数学工具类
float f = 0.1F; //0.1
double d = 0.1; //0.1
System.out.println(f==d); //false
System.out.println(f); //0.1
System.out.println(f); //0.1
float f1 = 2323232323232323F;
float f2 = f1 + 1;
System.out.println(f==d); //true
- 浮点数是有限的,离散的,存在舍入误差,是一个约数
- 最好完全避免使用浮点数
字符拓展
- 字符本质是数字,可以转为数字
- 编码 Unicode
- 转义字符
类拓展 (此时,类还没有讲)
//类
String sa = new String("hello world");
String sb = new String("hello world");
String sc = "hello world";
String sd = "hello world";
System.out.println(sa == sb); //false
System.out.println(sc == sd); //true
引用类型
reference type
- 类
- 接口
- 数组
4.5 类型转换
强制转换:高到低
自动转换:低到高
byte,short,char ---> int ---> long ---> float ---> double
低---------------------------------------------------------------->高
注意点:
- 不能对boolean值进行转换
- 不能进行不相关类型的转换
- 高转低使用强制转换
- 可能存在溢出或精度问题
JDK7 新特性 数字之间可以使用下划线分割
int money = 10_0000_0000;
System.out.println(money);//1000000000
4.6 变量常量
变量
Variable
- 类型:必须声明类型
- 变量名:必须是合法的标识符
- 作用域:变量的有效范围
变量可以分为三类:
- 类变量:独立于方法之外的变量,用 static 修饰。
- 实例变量:独立于方法之外的变量,不过没有 static 修饰。从属于对象,如果不初始化就是类型的默认值。
- 局部变量:类的方法中的变量。
public class Variable{
static int allClicks=0; // 类变量
String str="hello world"; // 实例变量
public void method(){
int i =0; // 局部变量
}
}
常量
Constant
-
初始化(initialize)之后不能再改变其值
-
其变量名一般用大写
-
使用final关键字来定义
-
final是一个修饰符,修饰符不存在先后顺序
命名规范
- 变量,方法,类名:见名知意
- 常量:大写字母和下划线
- 类名:首字母大写和驼峰原则
- 类成员变量:首字母小写和驼峰原则
- 局部变量:首字母小写和驼峰原则
- 方法名:首字母小写和驼峰原则
4.7 运算符
- 算术运算符:+,-,*,/,%,++,--
- 关系运算符:>,<,>=,<=,==,!=
- 位运算符: &,|,^,~,<<,>>,>>>
- 逻辑运算符: &&,||,!
- 赋值运算符: = ,*= ......
- 其他运算符: ?:,instanceof
运算符优先级
4.8 包机制
为了更好地组织类,Java提供了包机制,用于区别类的命名空间
包语句的语法格式:
package pkg1[. pkg2[. pkge ...]];
一般用公司的域名倒置作为包名
使用import导入包
import package1[.package2...].(classname|*);
4.9 JavaDoc
JavaDoc命令是用来生成自己的API文档的
参数信息
- @author 作者名
- @version 版本号
- @since 需要指明最早使用的JDK版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
命令行生成
javadoc -encoding UTF-8 -charset UTF-8 DocTest.java
IDEA生成
Tools: Generate JavaDoc
Output directory: select folder
Local: zh_CN
Other command line arguments: -encoding utf-8 -charset utf-8
5 流程控制
5.1 用户交互
Java为我们提供了用于程序和用户交互的一个工具类,我们可以获取用户输入。java.util.Scanner是Java5的新特性,我们可以使用Scanner来获取用户的输入。
基本语法
Scanner scanner = new Scanner(System.in);
我们可以通过Scanner类的next()与nextLine()方法来获取输入的字符串。
一般来说,我们需要在使用前通过hasNext()和hasNextLine()来判断是否还有输入的数据。
//凡是属于IO流的类,如果使用完不关闭会一直占用资源
scanner.close();
next()方法
- 一定要读取到有效字符后才会结束输入
- 对于有效字符之前的空白,next方法会自动将其去掉
- 对于有效字符之后的空白,next方法将其视为分隔符或结束符
- 所以next方法无法得到含空格的字符串
nextLine()方法
- 以Enter作为结束符,返回的是按下Enter之前的字符串
- 可以获得含空格的字符串
Scanner进阶
Scanner scanner = new Scanner(System.in);
//Scanner还有许多方法用来接受各种类型的数据
scanner.nextInt();
scanner.nextFloat();
5.2 顺序结构
基本结构,没有特殊声明就顺序一条一条执行
5.3 选择结构
if
单选择 if
双选择 if else
多选择
嵌套
switch
多选择
switch case 语句判断一个变量与一系列值中的某一个是否相等,每个值称为一个分支。
其中的变量类型可以是
- byte,short,int,char
- 从Java SE7 开始支持String
- case标签必须为字符串常量或字面量
int i = 10;
switch(i){
case 1:
//语句
break;
case 2:
//语句
break;
default:
//语句
}
break
跳出
continue
跳过本次
goto
goto虽然是Java的保留字,但是没有在正式语言中得到应用
Java没有goto
带标签的break和continue
标签:标识符后面跟一冒号 如:lable:
break,continue通常只中断当前循环,随标签一起使用会中断到标签处
对于Java来说唯一用到标签的地方是在循环语句之前。在循环语句之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环。
int count = 0; //输出101 到 150 之间的所有素数 outer: for (int i =101;i<150;i++){ for (int j=2;j<i/2;j++){ if(i%j==0) continue outer; } System.out.println(i + " "); }
5.4 循环结构
while
while(i<100){
System.out.println(i++);
}
do...while
do{
System.out.println(i++);
}while(i<100)
相比于while循环,即使条件不满足也会执行一次,即do...while保证代码至少也会执行一次
for
for(int i=0;i<100;i++){
System.out.println(i);
}
for更适合循环次数在执行前就已经知道的情况,如果不知道可以使用while或者do...while
增强for
主要用于遍历数组和集合对象
for(int number:numbers){
System.out.println(number);
}
5.5 练习
打印九九乘法表
for (int i = 1;i <=9;i++){
for(int j = 1;j<=i;j++){
System.out.print(i+ "*"+j+"="+i*j+" ");
}
System.out.println();
}
打印三角形
public class Triangle {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 5;j>=i;j--){
System.out.print(" ");
}
for (int j = 1;j<=i;j++){
System.out.print("*");
}
for (int j = 1;j<i;j++){
System.out.print("*");
}
System.out.println();
}
}
}
6 方法
6.1 什么是方法
Java方法是语句的集合,放在一起完成一个功能
解决一个问题的步骤的有序组合
方法设计原则
一个方法只完成一个功能 方法的原子性
6.2 方法的定义及调用
方法的定义
方法包含一个方法头和一个方法体
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- 返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
方法的调用
调用方法:对象名.方法(实参列表)
Java支持两种调用方法
-
当方法有返回值时,方法调用通常被当作一个值
int larger = max(30,40);
-
当方法返回值为void时,方法调用是一条语句
System.out.println("Hello world!");
值传递
值传递(pass by value)是指在调用方法时将实际参数复制一份传给方法,这样在方法中对参数进行修改将不会影响到参数
Java是值传递
引用传递
引用传递(pass by reference)是指在调用方法时将实际参数的地址直接传给方法,这样在方法中对参数进行修改将会影响到参数
区别
根本区别:是否创建副本(copy)
值传递和引用传递的区别并不是传递的内容。而是实参到底有没有被复制一份给形参。在判断实参内容有没有受影响的时候,要看传的的是什么,如果你传递的是个地址,那么就看这个地址的变化会不会有影响,而不是看地址指向的对象的变化。就像钥匙和房子的关系。
你有一把钥匙,当你的朋友想要去你家的时候,如果你直接把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。
你有一把钥匙,当你的朋友想要去你家的时候,你复刻了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。
但是不管上面的情况,如果你的朋友拿着你给他的钥匙进你家,把电视砸了,这就产生影响了。但钥匙还是钥匙,判断值传递还是引用传递时,你看的是钥匙,而不是房子里的其他东西。
注意:
关于Java值传递,引用传递的相关知识在面试中也经常会被问到,注意理解。
6.3 方法重载
什么是重载
在一个类中,方法名相同,但是参数不同
重载规则
- 方法名必须相同
- 参数列表必须不同
- 参数个数不同
- 参数类型不同
- 参数排列顺序不同
- 方法返回类型可以相同也可以不同
- 仅仅返回值类型不同不能成为方法的重载
6.4 命令行传参
运行程序前再传参数给它,传递命令行参数给main()函数实现
public class CommandLine {
public static void main(String args[]){
for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
运行这个程序,结果如下所示:
$ javac CommandLine.java
$ java CommandLine this is a command line 200 -100
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100
6.5 可变参数
JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。
方法的可变参数的声明如下所示:
typeName... parameterName
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。
public class VarargsDemo {
public static void main(String args[]) {
// 调用可变参数的方法
printMax(34, 3, 3, 2, 56.5);
printMax(new double[]{1, 2, 3});
}
public static void printMax( double... numbers) { // 可变参数
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0];
for (int i = 1; i < numbers.length; i++){
if (numbers[i] > result) {
result = numbers[i];
}
}
System.out.println("The max value is " + result);
}
}
6.6 递归
什么是递归
方法自己调用自己
递归可以用来将一些复杂大规模问题转换成一些小规模类似问题
递归可以写成循环
递归结构
- 递归头:什么时候不调用自身,即规模小到可以直接解决。没有的话会死循环。
- 递归体:什么时候调用自身。
能不用递归就不用递归,栈的空间使用完就会出错。