一、数据类型
1.基本数据类型
包括整数类型、字符类型、浮点类型、布尔类型
整数类型:byte(1字节)、short(2字节)、int(4字节)、long(8字节)
字符类型:char(2字节)
浮点类型:float(4字节)、double(8字节)
布尔类型:boolean(1位)
2.基本类型的类型转换
1)自动类型转换
当任何基本类型的值和字符串值进行连接运算时,基本类型都将自动转换为字符串类型。例:int a = 5; String test = a + “”;
2)强制类型转换
3)表达式类型的自动提升
Java表达式中自动提升规则:1所有的byte、short、char类型将自动提升为int类型。2整个算数表达式的数据类型自动提升到与表达式中最高等级操作数相同的类型。
示例:byte a = 1; short b = 2; char c = ‘w’; double d = 5.6;
double e = a + b + c + d;
3.直接量
直接量是指在程序中通过源代码直接指定的值。
能指定直接量的通常只有3中类型:基本类型、字符串类型和null类型。
对字符串直接量,当程序第一次使用字符串直接量时,Java会将字符串直接量缓存在常量池中,当后面程序再次用到该字符串直接量时,Java会直接使用常量池中的字符串直接量。
二、流程控制
1.switch分支语句
switch语句后面的控制表达式的数据类型只能是byte、short、char、int类型、枚举类型。Java 7中新增了String类型的支持。
switch(expression){
case(condition1):
statement(s);
break;
case(condition2):
statement(s);
break;
default:
statement(s);
}
2.循环结构
break可以结束整个循环,而continue可以结束本次循环。
三、数组
1.理解
Java的数组变量是一种引用类型的变量,数组变量并不是数组本身,它只是指向堆内存中的数组对象。如:int[] a;
Java的数组可以存储基本类型的数据,也可以存储引用类型的数据,只要所有数组元素具有相同的类型即可。
2.数组的初始化
初始化:就是为数组的数组元素分配内存空间,并为每个数组元素赋初值。
Java中数组必须先初始化后才可使用。
数组初始化有两种方式:静态初始化和动态初始化。
Java数组是静态的,一旦初始化完成,数组元素的内存空间分配即结束,程序只能改变数组元素的值,不能改变数组长度。
3.静态初始化
静态初始化:初始化时由程序员显式指定每个数组元素初始值,由系统决定数组长度。
示例:int[] a = newint[]{1,2,3,4,5}; 或者 int[] a = {1,2,3,4,5};
对静态初始化而言,程序无需指定数组长度,指定a的数组元素后,可知其数组长度为5。
4.动态初始化
动态初始化:初始化时程序员只指定数组长度,由系统为数组元素分配初始值。
示例:String[] book = new String[5];
指定初始值时,系统将按如下规则分配初始值:
数组元素类型是基本类型中的整数类型(byte、short、int、long),数组元素值为0。
数组元素类型是基本类型中的浮点类型(float、double),数组元素值为0.0。
数组元素类型是基本类型中的字符类型(char),数组元素值为’\u0000’。
数组元素类型是基本类型中的布尔类型(boolean),数组元素值为false。
数组元素类型是引用类型(类、接口、数组),数组元素值为null。
5.基本类型数组的初始化
对于基本类型数组而言,数组元素的值直接存储在对应的数组元素中。
则基本类型数组的初始化为:程序先为数组分配内存空间,然后将数组元素值存入其中即可。
示例:int[] a; a = {1,2,3,4,5};
6.引用类型数组的初始化
引用类型数组的数组元素依然是引用类型,因此数组元素里存储的是引用,它指向引用变量引用的对象(包括数组和Java对象)。
示例:
class Person{}
public class test
{
Person[] students;
students = newPerson[2];
Person zhao = new Person();
Person qian = newPerson();
students[0] = zhao;
students[1] = qian;
}
7.多维数组
如果从数组底层的运行机制上来看,是没有多维数组的。
示例:int[][] a;
Java语言采用上面格式来定义二维数组,但实际上还是一位数组,只是数组元素也是引用,该引用指向一维数组。
1) 二维数组初始化
1静态初始化
String[][] str1 =new String[][]{new String[3],new String[]{“hello world”}};
String[][] str2 ={ new String[3],new String[]{“hello world”}};
2动态初始化
int[][] a; //定义一个二维数组
a = new int[4][]; //把a当成一位数组,初始化a是一个长度为4的数组.
a[0] = new int[2]; // a数组元素亦引用
a[0][1] = 7;
或者
int[][] d =[3][4];
四、面向对象
面向对象三大特征:封装、继承、多态
1.成员变量和局部变量
与成员变量不同的是,局部变量必须显式初始化,否则不可以访问。
示例:
public static void main(String[] args)
{
int a ;
//System.out.println(a); //此写法错误,因为a没有显式初始化
}
2.成员变量的初始化
1)类变量的初始化时机:
1定义类变量时指定初始值
2静态初始化块中对类变量指定初始值
2) 实例变量的初始化时机
1定义实例变量时指定初始值
2非静态初始化块中对实例变量指定初始值
3构造器中对实例变量指定初始值
其中1、2两种方式比3更早执行,但1、2的执行顺序与它们在程序中的排列顺序有关(同样适用于类变量)。
当系统加载类或者实现类时,会自动为成员变量分配内存空间,并在分配内存后,为其指定初始值。
示例:
class Person
{
String name;
static int age;
}
public class test
{
public staticvoid main(String[] args)
{
Personp1 = new Person();
Person p2 = new Person();
p1.name = “李明”;
p2.name = “呵呵”;
p1.age = 33;
}
}
1当程序第一次执行Person p1 = new Person();时,如果是第一次使用Person类,系统会加载Person类,并初始化该类。在类的准备阶段,系统会为类Field分配内存空间并指定默认初始值(该实例中即为age,为age分配内存并赋初始值:0)。
2接着创建一个Person对象,并把Person对象赋给p1变量,Person对象包含了实例Field(即name),实例Field是在创建实例时分配内存空间并指定初始值的(即为name分配内存并赋默认初值:null)。
3 Person p2 = new Person();同p1。
3.局部变量的初始化
局部变量定义后,必须经过显式初始化才能使用,系统不会为局部变量执行初始化。
局部变量总是保存在其所在方法的栈内存中。
4.访问控制符
Java有4个访问控制级别:
pricate
default
proteceed
public
同一个类
√
√
√
√
同一个包
√
√
√
子类中
√
√
全局范围内
√
5.继承
子类不能获得父类的构造器。
当程序创建一个子类对象时,系统不仅会为该类中定义的实例变量分配内存空间,还会为它从父类继承得到的实例变量分配内存空间,即使子类中定义了与父类中同名的实例变量。此时若实例变量同名,子类中实例变量会隐藏父类中实例变量,可通过super来访问父类中的实例变量。若父类中实例变量与子类实例变量不同名,可在子类中直接调用父类中定义的实例变量。
6.多态
1)多态
Java引用变量有两种类型:编译时类型和运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋值时赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就会出现多态。
示例:
下例中,
BaseClass baseClass = new SubClass(); 中,baseClass引用变量的编译时类型是BaseClass,运行时类型是SubClass,当运行时调用该引用变量的方法时,其方法行为总是表现出子类方法的行为特征,而不是父类方法的行为特征,这就可能出现:相同类型的变量,调用同一个方法时呈现不同的行为特征,即多态。
与方法不同的是,对象的Field则不具备多态性。比如下例中System.out.println(baseClass.book);输出的是并不是SubClass中定义的实例Field,而是BaseClass中的实例Field。
【注】引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时
则执行它运行时类型所具有的方法。因此,编写Java代码时,引用变量只能调用声明该变量时所用类里包含的方法。
通过引用变量来访问其包含的实例Field时,系统总是视图访问它编译时类型所定义的Field,而不是运行时类型所定义的Field。
运行结果:
2)引用变量的强制类型转换
编写Java代码中,引用变量只能调用它编译时类型的方法,而不能调用它运行时类型的方法,即使它实际所引用的对象包含该方法。如果需要让这个引用变量调用它运行时类型的方法,则必须把它强制转换成运行时类型。
引用类型之间的转换只能在具有继承关系的两个类型之间进行,否则编译出错。如果试图把一个父类实例转换成子类类型,则这个对象必须是子类实例(即编译时为父类类型,运行时类型是子类类型,否则会报ClassCastException异常)。
考虑到强转时的异常,通常转换前通过instanceof来判断是否可以转换成功。
Object obj = “hello”;
String objPri = (String)obj;
if(obj instanceof String){
String str =(String)objPri;
}
Instanceof运算符的前一个操作数通常是一个引用,后一个操作数是一个类(或接口),用于判断前面的对象是否是后面的类,或者子类、实现类的实例。是的话,返回true,否则false。instanceof运算符前面的操作数的编译时类型要么与后面的类相同,要么与后面的类具有父子继承关系。
示例:
运行结果:
7.Java7 增强的包装类
1)把字符串类型的值转换为基本类型
1 利用包装类的parseXxx(String s)静态方法
2 利用包装类的Xxx(String s )构造器
2)把基本类型转换为字符串:
1 利用String类的valueOf()方法。
2 把基本类型变量和””进行连接运算,系统会自动把基本类型转换为字符串。
实例:
运行结果:
3) java会将Integer的-128~127之间的值放到字符串常量池中,可多次调用。
示例:
运行结果:
8.枚举
1)枚举类特点:
1使用enum定义的枚举类默认继承java.lang.Enum类,而不是Object。
2 使用enum定义、非抽象的枚举类默认使用final修饰,因此枚举类无派生类。
3枚举类构造器只能使用private修饰,若省略修饰符,默认为private。
4 枚举类所有实例必须在枚举类的第一行显式列出。
5 枚举类提供了values方法,可方便遍历所有枚举值。
6使用枚举实例时,总是通过EnumClass.variable的形似来访问。
示例:
运行结果:
五、与运行环境交互
1.获取键盘输入
1 使用Scanner获取键盘输入
Scanner默认以空格为分隔符,可通过Scanner的useDelimiter(String pattern)方法设置新的分隔符。Scanner还可获取文件内容:Scanner sc = new Scanner(newFile(“test.java”));
示例1(按空格为分隔符读取):
示例2(按行来读取):
2 使用BufferedReader获取键盘输入
BufferedReader是IO流中的字符、包装流,System.in是字节流,要用转换流InputReader。是按行读取的。