第二章 Java语言基础

标识符与关键字
Java语言字符集采用16位Unicode字符编码
Java关键字及作用

标识符命名规则:
以字母开头的字母数字序列:字母(大小写英文字母、下划线_、符号$),数字(0-9),不能使用关键字

基本数据类型
在这里插入图片描述

整数类型 字节数 取值范围
字节型byte 1 -2^7 ~ 2^7 - 1
短整型short 2 -2^15 ~ 2^15 -1
整型int 4 -2^31 ~ 2^31-1
长整型long 8 -2^63 ~ 2^63-1
单精度浮点数float 4 具体百度吧
双精度浮点数double 8 具体百度吧

变量与常量
变量:
保存在程序中可以被改变的数据,四要素(名字、类型、值、作用域)

最终变量:
采用关键子final声明的变量,只能进行一次赋值

final int value;  // 声明时未赋值
value = 100;      // 只能进行一次赋值

常量:直接常量、符号常量
直接常量
程序中直接引用的常量,包括数值型常量、字符串常量

符号常量
保存在程序中不能被改变的数值,常量名是标识符,用关键子final声明
Java与约定常量标识符全部用大写字母表示

final int MAX = 100;
final double PI = 3.1415926;

运算符与表达式
1)算术运算符
单目运算符:+(正)、-(负)、++(自增)、–(自减)
双目运算符:+(加)、-(减)、*(乘)、/(除)

2)关系运算符
运算结果为布尔类型
==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、 <=(小于等于)

3)位运算符
单目运算符:~(非)
双目运算符:&(与)、|(或)、^(异或)、<<(左移位)、>>(右移位)、>>>(无符号右移位)

4)逻辑运算符
单目运算符:!(非)
双目运算符:&(与)、|(或)、^(异或)、&&(条件与)、||(条件或)

5)赋值运算符
assignment(=、+=、-=、*=、/=、&=、|=、^=、<<=、>>=、>>>=)

6)类型强制转换符
(int)(98.4+0.5)

7)条件运算符
子表达式1 ? 子表达式2 :子表达式3;

8)括号运算符
用于改变表达式中运算符的优先级

9)字符串连接运算符
+ System.out.println("max =" +max);

10)点运算符
. 用于分隔包、子包、类、类中成员

11)对象运算符
instanceof 判断一个对象是否属于指定类或其子类,结果为布尔类型

12)new运算符
new运算符用于申请数组的存储空间,创建对象

运算符的优先级及结合性
在这里插入图片描述
运算符的类型兼容原则

byte > short > int > long > float > double
       char  > int > long > float > double
1.0+1        // 2.0
1.0 == 1     // true
'a' + 1      // 98
(char)('a' + 1)  // 'b'
'a' == 97    // true
'a'| 2       // 99
boolean b = 0;   // 语法错,布尔类型不是整数
true == 1;       // 语法错,布尔量与整数不可运算
!0               // 语法错,整数不可逻辑运算
int x,y,z;
x>y>z            // 语法错,必须写成x > y && y > z
++x||++y&&++z    // 语法错,整数不可逻辑运算
++x|++y&++z      // 整数进行位运算
x>y & y>z        // 逻辑运算,没有短路计算功能

long big = 6;    // 自动转化long
float z = 0.0    // 语法错,0.0默认为double,赋值不相容

流程控制语句
java语言的语法和c/c++类似,但是不支持goto
在这里插入图片描述

i+1;   // java中语法错误,没有赋值功能的表达式不能成为语句

if ()
	if()
else ...;
//  else 与第二个if匹配, java中else总是与最近的if匹配

switch(表达式)
{
	case 常量表达式1: ... ; break;
}
// switch 表达式支持 String

// Fibonacci 数列
public class Fibonacci
{
	private static void main(String args[]){
		short i = 0, j = 1;
		do{
			System.out.println(" "+i+" "+j);
			i = (short)(i+j);
			j = (short)(i+j);
		}while(i < 0);  // short 整数溢出循环停止
	}
}

一维数组

// 声明
int a[];
int[] a;

// 分配空间
a = new int[3];
int alen = 3;
a = new int[alen]; // 常量变量均可

// 数组长度
a.length

// 数组元素表示及运算
 a[0] - a[a.length - 1]; 

// 数组声明时赋值
int a[] = {1,2,3,4};

// 数组元素的初始化
java对所有使用new运算符动态分配的存储单元都进行初始化

// 逐元循环
int a[] = {1,2,3};
for(int value: a){
	System.out.print(" "+value);
}

// 数组的引用模型
int a[] = {1, 2, 3}, b[];
b = a;       // 引用赋值,相当于两个指针赋值
b[1] = 10; 
a == b;      // true

b[] = new int[a.length];
for(int i = 0; i < a.length; i++){ // for(int i: a)
	b[i] = a[i];
}
a == b;     // false 

// 释放数组
b = null;  // 通常,程序不需要释放数组,java将自动收回不再使用的数组占用的存储空间

二维数组

// 声明二维数组
int mat[][];
mat= new int[4][5];
or
int mat[][] = new int[4][5];

// 声明时初始化赋值
int mat[][] = {{1,2,3},{4,5,6}};

// 二维数组长度
mat.length         // 二维数组的行数
mat[0].length      // 二维数组的列数

// 引用模型
mat[0][0] - mat[mat.length - 1][mat[0].length - 1];

// 不规则二维数组
int mat[][] = new int[3][];    // 申请第一维存储空间
mat[0] = new int[4];           // 申请第二维存储空间
mat[1] = new int[3]; 

静态函数
java语言没有全局函数,函数声明在类中,称为成员方法,有静态方法和全局方法两种
可以声明形式参数为final, 函数方法体中不可以对其赋值
java不支持类之外的全局变量

实际参数向形式参数传递原则
方法调用时给出的参数称为实际参数,可以是常量、变量、表达式或方法调用等,多个参数用逗号分隔。实际参数必须在数据类型、参数个数及次序等三方面与形式参数–对应。
方法调用的参数传递原则与赋值相同,实际参数向实际参数赋值。传递方式因形式参数的数据类型不同而不同,若是基本数据类型,则传递值;若是引用数据类型,则传递引用。

常量形式参数

public static int[] random(final int n){    // 声明n为常量,方法体中不能赋值
	n = 10;       // 错, 不可以对常量赋值
}

public static int[] random(final int a[]){  // 声明a数组为常量,方法体中不可以修改引用
	a[0] = 0;        // 可以更改常量数组元素值
	a = new int[3];  // 错,不可以对常量赋值,即不能改变数组引用
}

可变形式参数

public static void print(int... value)   // 可变形式参数,可将value视为int[]类型, int... 不能与int[] 重载

方法重载
一个类中有多个同名方法但带有不同参数列表,称为方法重载。
参数列表不同:数据类型,个数,次序不同 (不能以返回值相区别)

java方法声明没有参数默认值,避免二义性。
public static int[] random(int n, int max)
public static int[] random(){ return random(10, 100);}

int abs(int a)
long abs(long a)
float abs(float a)
double abs(double a)

递归方法
递归定义必须满足:
1) 边界条件:至少有一条初始定义是非递归的
2)递推通式:由已知函数值逐步递推出未知函数值

字符串
java字符串String是一个类,属于引用数据类型

字符串的基本数据类型特性
1)字符串常量
字符串是由双引号括起来表示的字符序列,可以包含转义字符(“Hello!”, “汉子\n”),字符串只能在同一行中,不可换行,空串长度为0,一个字母,汉字均是java的一个字符,数据类型为char, 占2字节。
约定字符串中首字符的序号为0, -1表示某字符不在指定字符串中。

2)字符串的变量及运算

// 赋值运算
String s1;           // 声明变量
String s2 = "abc";   // 声明变量时赋初值  // s2非字符数组!!!
String s3 = s2;      // 引用赋值
String s4 = String("abc");

// 单引号括起来的是字符常量,如'a';用双引号括起来的是字符串常量,如"a";所以有空串"",没有'';两种数据类型不兼容
String s5 = 'a';     // 错,类型不兼容

// 连接运算
s1 = "abc" + "efg";
s2 += "abc";   // 只有 += 复合赋值运算符可以用在字符串上

String str = "" + 'a';  // 结果为"a"
int i = 10;
System.out.println("i="+i); // 结果为"i=10"

// 字符串不是字符数组
str[1]='a';         // 错,没有该表达式
str.charAt(i);      
StringBuffer::SetcharAt(i);   // 错,常量字符串不能赋值

字符串的类特性
String 是一个类

public final class String implements java.io.Serializable,Comparable<String>,CharSequence{
	public String(byte value[])                    // 由默认编码的字节数组构造字符串
	public String(byte value[], int i, int n)      // 由value数组从i开始长度到n的若干字节构造串
	public int length()                            // 返回字符串的长度
	public char charAt(int i)                      // 返回第i(i >= 0)个字符
	public boolean equals(Object obj)              // 比较当前串与obj引用的串是否相等
	public String substring(int begin)             // 返回从begin(>=0) 开始到尾串的子串
	public String substring(int begin, int end)    // 返回从begin开始到end-1的子串
	public static String format(String format, Object... args) // 返回format指定格式字符串,可变形参
}

format 格式字符串定义:%[参数索引|$][宽度][.精度]变换类型
变换类型取值:
b(boolean)c(字符)C(字母大写)d(十进制整数)o(八进制整数)x(十六进制整数)e(浮点数指数形式)f(浮点数小数形式)s(字符串字母小写)S(字符串字母大写)

从标准输入流中读取一行字符串,再转换位整数

public class Input {

    public static String readLine() throws java.io.IOException
    {
        System.out.print("输入一行字符串,以回车换行符结束: ");
        byte buffer[] = new byte[512];
        int count = System.in.read(buffer);     // 从标准输入流读字节到缓冲区buffer
                                                // read()方法接收字母和汉字,每个字符长度都是 1
        System.in.close();                      // 关闭标准输入流
        return (count == -1) ? null : new String(buffer, 0, count-2); // 不计回车换行符
    }

    public static void main(String[] args) throws java.io.IOException{
        String s = readLine();
        int value = MyInteger.parseInt(s);        // 将字符串转化为整数
        System.out.println("MyInteger.toString(" + value + ",2)=" + MyInteger.toString(value,2));
        System.out.println("MyInteger.toString(" + value + ",16)=" + MyInteger.toString(value,16));
    }
}
public class MyInteger {

    // 返回将字符串s转换的整数,自动识别进制,若不能识别整数,则抛出格式异常
    public static int parseInt(String s) throws NumberFormatException{
        if(s == null) throw new NumberFormatException("null");
        char ch = s.charAt(0);             // 获得首字符,识别进制
        int value= 0, i = 0, sign = 1, radix = 0;
        if(ch >= '1' && ch <= '9' || ch == '+' || ch == '-'){  // 10进制
            radix = 10;
            if(ch == '+' || ch == '-' ){  // 跳过正负号
                i++;
            }
            sign = ch == '-' ? -1 : 1;
        }else if (ch == '0' && s.charAt(1) != 'x'){            // 8进制
            radix = 8;
            i++;
        }else if (ch == '0' && s.charAt(1) == 'x'){            // 16进制
            radix = 16;
            i+=2;
        }else
            throw new NumberFormatException("整数不能识别\'" + ch + "\'字符");

        while(i < s.length()){
            ch = s.charAt(i++);
            if(ch >= '0' && ch-'0' < radix)                    // radix <= 10 识别 0-9
                value = value * radix + ch - '0';
            else if (radix == 16 && ch >= 'a' && ch <= 'f')
                value = value * radix + ch - 'a' + 10;
            else if (radix == 16 && ch >= 'A' && ch <= 'F')
                value = value * radix + ch - 'A' + 10;
        }
        return value * sign;
    }

    public static String toString(int value, int radix){
        if(radix == 10) return value + "";
        if(radix == 2 || radix == 4 || radix == 8 || radix == 16){
            int mask, n = 0;                                  // mask 获得radix最大进制数
            for(mask = radix - 1; mask > 0 ; mask >>>=1){     // n 获得mask的二进制位数
                n++;
            }
            mask = radix - 1;
            char buffer[] = new char[(int)(32.0/n + 0.5)];    // 存储一个int表示radix进制的各位
            for(int i = buffer.length - 1; i >=0; i--){
                int bit = value & mask;                       // 获得radix进制的个位数字
                buffer[i] = (char)(bit <= 9 ? bit + '0' : bit + 'a' - 10);
                value >>>= n;                                 // 右移n位,高位补0, 即value除以radix
            }
            return new String(buffer);
        }
        throw new IllegalArgumentException("radix 参数值" + radix + "表示的进制无效");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章