标识符与关键字
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 + "表示的进制无效");
}
}