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()方法

  1. 一定要读取到有效字符后才会结束输入
  2. 对于有效字符之前的空白,next方法会自动将其去掉
  3. 对于有效字符之后的空白,next方法将其视为分隔符或结束符
  4. 所以next方法无法得到含空格的字符串

nextLine()方法

  1. 以Enter作为结束符,返回的是按下Enter之前的字符串
  2. 可以获得含空格的字符串

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+"\t");
	}
	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 递归

什么是递归

方法自己调用自己

递归可以用来将一些复杂大规模问题转换成一些小规模类似问题

递归可以写成循环

递归结构

  • 递归头:什么时候不调用自身,即规模小到可以直接解决。没有的话会死循环。
  • 递归体:什么时候调用自身。

能不用递归就不用递归,栈的空间使用完就会出错。