Java基础-chap2-Java语言基础

第二章 Java语言基础


2.1 关键字

  • 被赋予特殊含义的单词,关键字都是小写

    2.2 标识符

    • 在程序中自定义的一些名称。
    • 由26个英文字母大小写,数字:0-9 符号:_$组成。
    • 定义合法标识符规则:1,数字不可以开头。
      2,不可以使用关键字。
    • Java中严格区分大小写。
    • 注意:在起名字时,为了提高阅读性,要尽量有意义

2.3 注释

  • 对于单行和多行注释,被注释的文字,将会被Java编译器忽略,不会被JVM解释执行
  • 对于文档注释,是java特有的注释,其中注释内容可以被JDK提供的工具javadoc所解析,生成一套以网页文件形式体现的改程序的说明文档。
  • 注释是一个程序员必须要具有的良好变成习惯。
  • 初学者编程可以养成习惯:先写注释再写代码。
    例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
需求:练习一个hello world程序。

思路:
1,定义一个类,因为Java程序都定义在类中,java程序都是以类的形式存在的,类的形式其实就是一个字节码文件最终体现。
2,定义一个主函数。为了让该类可以独立运行。
3,因为演示hello world,在控制台上看到该字样,所以需要使用输出语句完成。

步骤:
1,用class关键字来完成类的定义,并起一个阅读性强的类名。
2,主函数:public static void main(String[] args)这是固定格式的。JVM认识。
3,使用输出语句:System.out.println("hello world");

*/



class Demo
{
//定义一个主函数,为了保证程序的独立运行。
public static void main(String[] args)
{
System.out.println("Hello World!");//这是输出语句,用于将括号中的数据打印到控制台上,ln可以在数据的结尾处换行。
}
}

将自己的思想通过注释先整理出来,再用代码去体现。
因为代码仅仅是思想的一种体现形式而已。
用于注解说明解释程序的文字就是注释
提高了代码阅读性

  • 注释可以进行程序的调试

格式:
单行注释

//这是许多程序语言通用单行注释

多行注释
/这是许多
程序语言
通用多行注释/

文档注释

/* 文档注释。
Java语言独有 /

2.4 常量和变量

常量

  • 常量表示不能改变的数值。
  • Java中常量分类:
    1,整数常量。所有整数
    2,小数常量。所有小数
    3,布尔(boolean)型常量。较为特有,只有两个数值。true false
    4,字符常量。将一个数字字母或者符号用单引号(’ ‘)标识。
    5,字符串常量。讲一个或者多个字符用双引号(” “)标识。
    6,null常量。只有一个数值就是:null
  • 对于整数:有四种表现形式。
  • 二进制:0,1,满2进1。byte 字节=8个二进制位(bit位),1KB=1024byte;1MB=1024KB;1GB=2014MB;1TB=1024GB。负数的二进制表现形式:对应的正数二进制取反加1。负数的二进制最高位是1
  • 八进制:0-7,满8进1。用0开头表示。八进制数,其实就是3个二进制位为1个八进制位。如023。
  • 十进制:0-9,满10进1。
  • 十六进制:0-9,A-F,满16进1。用0x开头表示。十六进制数,其实就是4个二进制位为1个十六进制位。如0x23。

  • 一个整数在内存中是用4个字节来表示,如6在内存中表示为0000-0000 0000-0000 0000-0000 0000-0110,-6为6对应的二进制数取反加1,1111-1010

变量

  • 变量的概念:
    • 内存中的一个存储区域
    • 该区域有自己的名称(变量名)和类型(数据类型
    • 该区域的数据可以在同一类型范围内不断变化
  • 为什么要定义变量:
    • 用来不断的存放同一类型的常量,并可以重复使用
  • 使用变量注意:
    • 变量的作用范围(一对{}之间有效)
    • 初始化值
  • 定义变量的格式:
    • 数据类型 变量名=初始化值;
    • 注:格式是固定的,记住格式,以不变应万变。
  • 理解:变量就如同数学中的未知数。

    数据类型

  • Java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存总分配了不同大小的内存空间。
  • 整数默认:int 小数默认:double(双精度浮点数)
  • byte 数据类型是8位、有符号的,以二进制补码表示的整数,范围-128(-2^7)~127(2^7-1),默认值是0;
  • short 数据类型是 16 位、有符号的以二进制补码表示的整数,范围-32768(-2^15)~32767(2^15-1),默认值是0;
  • int 数据类型是32位、有符号的以二进制补码表示的整数,范围-2,147,483,648(-2^31)~ 2,147,483,647(2^31 - 1),默认值是0,一般整形变量默认为int类型
  • long 数据类型是 64 位、有符号的以二进制补码表示的整数,范围-9,223,372,036,854,775,808(-2^63)~ 9,223,372,036,854,775,807(2^63 -1),默认值是0L(”L”理论上不分大小写,但是若写成”l”容易与数字”1”混淆,不容易分辩。所以最好大写。)
  • float 数据类型是单精度、32位、符合IEEE 754标准的浮点数,默认值为0.0f
  • double 数据类型是双精度、64 位、符合IEEE 754标准的浮点数,默认值为0.0d
  • boolean数据类型表示一位的信息,只有true和false两个取值,默认值为false
  • char类型是一个单一的16位Unicode(国际统一编码表)字符,范围\u0000(即为0)~\uffff(即为65535),char数据类型可以储存任何字符,可以根据ASCII码(American Standard Code for Information Interchange,美国信息交换标准代码)转换成数值后运算,如’A’=65, ‘a’=97;
  • 自动类型转换(也叫隐式类型转换)
  • 整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。
  • 转换从低级到高级
    如:int x = 3;
    byte b = 5;
    x = x + b; / /此时byte会自动提升为int,并与int相加得出结果
  • 强制类型转换(也叫显式类型转换)
  • 条件是转换的数据类型必须是兼容的。
  • 格式:(type)value type是要强制类型转换后的数据类型
    如:byte b = 3;
    b = (byte)(b+4); //强制类型转换。
  • 类型转换的原理
  • 什么时候要用强制类型转换?
  • 表达式的数据类型自动提升
    • 所有的byte型、short型和char的值将被提升到int型;
    • 如果一个操作数是long型,计算结果就是long型;
    • 如果一个操作数是float型,计算结果就是float型;
    • 如果一个操作数是double型,计算结果就是double型。
  • 分析
    • System.out.println(‘a’)与System.out.println(‘a’+1)的区别。

面试题
为什么以下代码运行时报错?

1
2
3
4
5
6
7
byte b = 4;
//若给定条件b = 3+7; <font color=#FF4500 size=3>3+7是常量</font>,可以赋值给b,因此run ok。
byte b1 = 3;
byte b2 = 7;
b = b1 + b2;
//b1和b2是变量,b为byte类型,如b1+b2的值超过-128~127范围则不能赋予b,因此run会报错可能丢失精度。
System.out.println(b);

2.5 运算符

算术运算符

  • 有四个:+ - * /
    % 取余,模运算,如5%2读作“五模以二”,结果为1,结果正负只参考被模数,如5%-2=1,-5%2=-1。
    +(连接符) 用于连接字符串,连接符两端都是字符串,如System.out.println(“5+5=”+5+5)输出为5+5=55,若改为System.out.println(“5+5=”+(5+5))输出为5+5=10。
    ++ 自增 a++; //a=a+1;
    难点

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    int i = 3;
    i++; //i = i + 1;
    System.out.println("i= "+i); //i++等价于i=i+1,结果为i=4。

    int i = 3 ;
    i = i++; //temp = i;
    i = i + 1;
    i = temp; //即先赋值,后运算。
    System.out.println("i=" + i ); //结果为i=3。

    int i = 3 ;
    i = ++i; //i = i + 1;
    temp=i;
    i = temp; //即先运算,后赋值。
    System.out.println("i=" + i ); //结果为i=4。
  • 自减
    这里除法/需特别注意,java是强类型语言,两个整数运算后仍是整数。
    例:

    1
    2
    3
    int x = 6370;
    x = x/1000*1000;
    System.out.println(x); //这里输出结果是6000,因为6370/1000=6.37,而结果类型为int整型,所以实际结果等于6,6*1000=6000。

赋值运算符

  • =
  • +=

    1
    2
    int a = 4;
    a+=2; //a = a + 2; 加和赋值操作符,它把左操作数和右操作数相加赋值给左操作数
  • -= 减和赋值操作符,它把左操作数和右操作数相减赋值给左操作数

  • *= 乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数
  • /= 除和赋值操作符,它把左操作数和右操作数相除赋值给左操作数
  • %= 取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数

面试题
1 short s = 3;
2 s+=4;
3 s = s + 4;
问:2&3有什么区别?
答:short在内存中占两个字节,整数默认类型为int,占4个字节,第3行s为变量,如果s取值较大+4,会超出short范围,则右边s+4不能赋予左边short类型的s。因此若用第三行编译会报错可能精度丢失。若用第2行不会报错,因为第2行+=是加和赋值操作,是一次运算,第3行是两次运算,先求和,再赋值,+=会有一个底层自动强转的过程,而第3行不会做自动强转。其实本题中s+=4;应该等价于s = (short) (s + 4);。

比较运算符

  • 比较运算符的结果都是boolean型,也就是要么是true,要么是false
  • 比较运算符“==”读作等等于,不能误写成“=”

逻辑运算符

  • 用于连接两个boolean类型的表达式
  • & 运算两边只有有一个是false,结果肯定是false,只有两边都为true,结果才是true
  • | 运算两边只要有一个是true,结果肯定是true,只有两边都为false,结果才是false
  • ^ 异或两边结果如果相同,结果是false,两边的结果不同,结果是true。一个数异或同一个数两次,结果还是这个数。利用该特性可以用于加密
  • ! 逻辑非运算符。用来反转操作数的逻辑状态

面试题:

  • && (短路) 只要左边为false,右边不进行运算直接得出false,类似电路中的短路(与&区别,&不管左边什么结果右边都运算),与&运算结果一样,但是运算过程有区别
  • ||(短路)只要左边为true,右边不进行运算直接得出true,类似电路中的短路(与|区别,|不管左边什么结果右边都运算),与|运算结果一样,但是运算过程有区别
    ###位运算符
    • 位运算是直接对二进制进行运算
    • 位运算可以使运算高效
    • a << b = a 2b; 如3<<2 = 3 22 = 12。
    • a >> b = a / 2b;
    • 无符号右移:数据进行右移时,高位出现的空位,无论原高位是什么,空位都用0补

三元运算符

  • 格式
  • (条件表达式)? 表达式1 : 表达式2
  • 如果条件为true,运算后的结果是表达式1
  • 如果条件为false,运算后的结果是表达式2
  • 三元运算符就是if else语句的简写格式,当if else运算后,有一个具体的结果时,可以简化为三元运算符
    • 示例:
  • 获取两个数中大数。
    1
    2
    int x=3,y=4,z;
    z = (x>y)?x:y; //z变量存储的就是两个数的大数

2.6 程序流程控制

判断结构

if 语句

  • 注意:上述三种格式均为单条语句,if(条件表达式)后面紧跟”{“,没有”;”
    • 大括号”{}”里面的内容根据前面的内容命名,如class后面紧跟的”{}”中的内容叫做类代码块
      public static void main后面大括号”{}”中的内容叫做主函数代码块,如果”{}”前面什么都没有,那么”{}”中的内容称为局部代码块。局部代码块的功能:限定局部变量的生命周期(作用域)

选择结构

switch语句

  • 格式:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    switch(表达式)   //只有byte, short, int, char.四种类型可以选择
    {
    case 取值1: //注意是冒号":"
    执行语句;
    break; //如果符合,跳出
    case 取值2:
    执行语句;
    break;
    ……
    default: //缺省、默认,即其他情况
    执行语句;
    break;
    }
  • if和switch的区别
  • if:
    1,对具体的值进行判断
    2,对区间的判断
    3,对运算结果是boolean类型的表达式进行判断
  • switch(相比if而言并不常用):
    1,对具体的值进行判断。对于几个固定值的判断,建议用switch语句,因为switch 语句会将具体答案都加载进内存。
    2,值的个数通常是固定的

循环结构 (loop)

while循环

  • 格式:
1
2
3
4
while (条件表达式)
{
执行语句;
}

Tips: ctrl + c终止控制台运行

do…while循环

  • 格式:
1
2
3
4
do
{
执行语句;
}while(条件表达式);
  • do…while语句的特点:无论条件是否满足,循环体至少执行一次

for循环(重要!)

  • 格式:

    1
    2
    3
    4
    for (初始化表达式; 循环条件表达式(即boolean表达式); 循环后的操作表达式)
    {
    执行语句; //循环体
    }
  • for循环执行的次数是在执行前就确定的。
  • 执行顺序:1~8
  • for和while的特点:
    1,for和while可以互换
    2,格式上的不同,在使用上有点小区别。
    如果需要通过变量来对循环进行控制,该变量只作为循环增量存在时,区别就体现出来了。
    
  • 什么时候使用循环结构?
    当对某些代码执行很多次时,使用循环结构完成。
    当对一个条件进行一次判断时,可以使用if语句。
    当对一个条件进行多次判断时,可以使用while语句。
    注意:在使用循环时,一定要明确哪些语句需要参与循环,哪些不需要。
    循环通常情况下,需要定义条件,需要控制次数

  • 嵌套语句结构

    • 大圈套小圈思想:对于一种重复的情况中的每一次重复都对应另一种情况的多次重复。
    • 例子:

      1
      2
      3
      4
      5
      6
      7
      for (int x = 0;x<3 ;x++ )
      {
      for (int y=0;y<4 ;y++ )
      {
      System.out.println("ok");
      }
      }
    • 分析:外循环每循环1次,内循环循环4次,总共循环3*4=12次。

    • Tips:
    • \”:双引号:如输出带双引号的hello world则应输入System.out.print( “\”hello world\””);
    • \n:换行符
    • \t:制表符
    • \b:退格
    • \r:按下回车键
    • 在Windows系统中回车符其实是由两个符号组成的:\r\n
    • 在Linux系统中回车符是:\n

      其他流程控制语句

    • break(跳出),continue(继续)
    • break语句应用范围:选择结构和循环结构
    • continue语句应用范围:循环结构
    • 这两个语句离开应用范围,存在时没有意义的
    • 这两个语句单独存在下面都不可以有语句,因为执行不到
    • continue语句是结束本次循环继续下次循环
    • 标号的出现,可以让这两个语句作用于制定的范围

2.7 函数

函数的定义

  • 函数就是定义在类中具有特定功能的一段独立小程序
  • 函数也称为方法

    • 函数的格式
      1
      2
      3
      4
      5
      修饰符 返回值类型 函数名(参数类型 形式参数1, 参数类型 形式参数2, ...)
      {
      执行语句;
      return 返回值;
      }
  • 函数名写作规范:首字母小写,若有多个单词则除第一个词以外其他词首字母大写

  • 返回值类型:函数运行后的结果的数据类型
  • 参数类型:是形式参数的数据类型
  • 形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数
  • 实际参数:传递给形式参数的具体数值
  • return:用于结束函数
  • 返回值:该函数运算后的结果,该结果会返回给调用者

函数的特点

  • 定义函数可以将功能代码进行封装
  • 便于对该功能进行复用
  • 函数只有被调用才会被执行
  • 函数的出现提高了代码的复用性
  • 对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果再最后一行可省略不写
  • 注意:
    1, 函数中只能调用函数,不可以在函数内部定义函数
    2, 定义函数时,函数的结果应该返回给调用者,交由调用者处理

函数的应用

  • 例子:需求:定义一个功能,完成两个整数的和的获取
  • 思路:既然定义功能,就是可以用函数来体现
  • 通过两个明确来完成。
  • 明确一:这个功能的结果是什么?
    是和。是功能的结果,所以该功能的返回值类型是int
    其实就是在明确函数的返回值类型
  • 明确二:这个功能实现过程中是否需要未知内容参与运算?
    有,加数和被加数。这就是函数的参数列表(参数的个数,参数的类型)
    其实就是在明确参数列表
  • 注意:返回值类型和参数类型没有直接关系。
  • 函数示例:
    1
    2
    3
    4
    5
    public static int add(int a,int b)
    {
    int sum = a+b;
    return sum;
    }

函数的重载(overload)

  • 概念:在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
  • 特点:与返回值类型无关,只看参数列表
    java是严谨性语言,如果函数出现调用的不确定性,会编译失败
  • 好处:提高阅读性,优化程序设计
  • 示例:
1
2
3
4
5
6
//返回两个整数的和
int add(int x,int y){return x+y;}
//返回三个整数的和
int add(int x,int y,int z){return x+y+z;}
//返回两个小数的和
double add(double x,double y){return x+y;}

2.8 数组

前言

  • 学习任何程序语言,具有容器功能的程序都应作为重点学习。
  • 如果数据出现了对应关系,而且对应关系的一方是有序的数字编号。并作为角标使用,这时就必须要想到数组的使用

数组的定义

  • 概念:同一种类型数据的集合。其实数组就是一个容器
  • 好处:可以自动给数组中的元素从0开始编号,方便操作这些元素
  • 格式1:

    元素类型[] 数组名 = new 元素类型[元素个数或数组长度];

    1
    int[] arr = new int[5];

使用情况:需要一个容器,但是不明确容器中的具体数据

  • 格式2:

    元素类型[] 数组名 = new 元素类型[]{元素,元素,……};

    1
    2
    int[] arr = new int[]{3,5,1,7};
    int[] arr = {3,5,1,7};//也可以简写为此行

使用情况:需要一个容器,存储已知的具体数据

数组的内存分配及特点

  • 寄存器
  • 本地方法区
  • 方法区
  • 栈内存
    内存分配:存储的都是局部变量,而且变量所属的作用域一旦结束,该变量就自动释放
    特点:生命周期短,更新速度快

  • 堆内存
    内存分配:存储的是数组和对象(其实数组就是对象)。凡是new建立的都在堆中
    特点:
    1,每一个实体都有首地址值 (C++中的指针,即Java中的引用
    2,堆内存中的每一个变量都有默认初始化值,根据类型的不同而不同。整数是0,小数0.0f,boolean false,char ‘\u0000’
    3,垃圾回收机制

数组常见操作

  • 对数组操作最基本的动作就是存和取
  • 核心思想:对角标的操作
  • 遍历:arr.length 表示数组的长度
1
2
3
4
5
System.out.println("length:"+arr.length);
for (int x=0;x<arr.length ;x++ )
{
System.out.println("arr["+x+"] = "+arr[x]+";");//输出效果:arr[0] = 89;
}//数组的正向遍历
  • 获取最值(最大值,最小值)
  • 排序(选择排序,冒泡排序)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//选择排序
public static void selectSort(int[] arr)
{
for (int x=0;x<arr.length-1 ;x++ )//外循环最后剩余的数不需要比较,故减1
{
for (int y=x+1;y<arr.length ;y++ )
{
if(arr[x]>arr[y])
{
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//冒泡排序
public static void bubbleSort(int[] arr)
{
for (int x=0;x<arr.length-1 ;x++ )
{
for (int y=0;y<arr.length-1-x ;y++ )
{
if (arr[y]>arr[y+1])
{
int temp = arr[y];
arr[y] = arr[y+1];
arr [y+1] = temp;
}
}
}
}

注意:以上代码面试使用,其实java中已经做好了排序功能,输入以下代码:

import java.util.*; 然后在主函数中输入Arrays.sort(arr); 即可自动对指定数组进行排序,此方法适合实际开发时使用

  • 折半查找(二分查找)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static int halfSearch(int[] arr,int key)
{
int max,min,mid;
min = 0;
max = arr.length-1;
mid = (max+min)/2;

while (arr[mid]!=key)
{
if (key>arr[mid])
{
min = mid + 1;
}
else if (key<arr[mid])
{
max = mid - 1;
}
if (max<min)
{
return -1;
}
mid = (max+min)/2;
}
return mid;
}

注意:以上代码面试使用,其实java中已经做好了二分查找功能,输入以下代码:

import java.util.*; 然后在程序中输入Arrays.binarySearch(arr,x); 即可自动对指定元素x进行二分查找。如果元素x在数组arr[]中存在,返回具体角标;如果不存在,返回的是 -插入点-1。此方法适合实际开发时使用

1
2
3
Integer.toBinaryString(x); //将十进制数x转化为二进制
Integer.toHexString(x);// 将十进制数x转化为十六进制
Integer.toOctalString(x);// 将十进制数x转化为八进制

数组中的数组

  • 二维数组[][]
  • 格式1:
1
int[][]arr = new int[3][2];

定义了名称为arr的二维数组
表示该二维数组中有3个一维数组
每一个一维数组中有2个元素
一维数组的名称分别为arr[0],arr[1],arr[2]
给第一个一维数组1脚标位赋值为78的写法是:arr[0][1] = 78;

  • 格式2:
1
int[][]arr = new int[3][];

二维数组中有3个一维数组
每个一维数组都是默认初始化值null
可以对这个三个一维数组分别进行初始化

1
2
3
4
5
6
7
8
9
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];

int[][] arr = new int[3][];

System.out.println(arr);//直接打印二维数组 结果:[[I@61064425 @左边[[表示二维数组
System.out.println(arr[0]);//直接打印二维数组中的角标0的一维数组 结果:null
System.out.println(arr[0][0]);//直接打印二维数组中的角标0的一维数组中角标为0的元素 结果:NullPointerException

二维数组内存图解

也可以写成

1
int[][] arr = {{3,1,7},{5,8,2,9},{4,1}};

编辑器:EditPlus
蓝色:关键字
红色:Java创建好的类

2.9 基本语法

  • 编写Java程序时,应注意以下几点:
  1. 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。
  2. 类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
  3. 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
  4. 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记Java是大小写敏感的),文件名的后缀为.java。(如果文件名和类名不相同则会导致编译错误)。
  5. 主方法入口:所有的Java 程序由public static void main(String []args)方法开始执行。
0%