Java基础
目录:
一、java语言的概述:
1.1dos命令
常用的dos命令:
dir:列出当前目录下的文件以及文件夹
md:创建目录
rd:删除目录
cd:进入指定目录
cd..:退回到上一级目录
cd\:退回到根目录
del:删除文件
exit:退出dos命令行
1.2JDK安装并配置path环境变量
1.3helloworld
1.源文件以.java结尾
2.源文件中可以有多个class声明的类3.类中可以有主方法(即main()方法),其格式是固定的4.main()方法是程序的入口,方法内是程序执行部分5.一个源文件中只能有一个声明位pulbic的类,同时要求此类的类名与源文件名一致。6.执行程序:①编译:javac.exe编译完,生成诸多个.cla
1.4注释
1.单行注释: //
2.多行注释: /**/
3.文档注释: /**
*
*/
4.解析源文件:
javadoc -d myodc - author -version hellojava.java
index.html
二、基本语法
2.1关键字&标识符
2.1.1关键字的定义和特点
>定义:被java语言赋予了特殊含义,用作专门用途的字符串(单词)
>特点:关键字中所有字母都为小写
<1>用于定义数据类型的关键字
class interface enum byte short int long
float double char boolean void
<2>用于定义数据类型值的关键字
true false null
<3>用于定义流程控制的关键字
if else switch case default while do for break
continue return
<4>用于定义访问权限修饰符的关键字
private protected public
<5>用于定义类、函数、变量的修饰符关键字
abstract final static synchronized
<6>用于定义类与类之间关系的关键字
extends implements
<7>用于定义建立实例及引用实例,判断实例的关键字
new this super instanceof
<8>用于异常处理的关键字
try catch finally throw throws
<9>用于包的关键字
package import
<10>其他修饰符关键字
native strictfp transient volatile assert
保留字
java保留字:现有的Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标记符时要避免使用这些保留字
byValue cast future generic inner operator outer rest var goto const
2.1.2标识符
>Java对各种变量、方法、类等要素命名时使用的字符序列称为标识符。
>凡是自己可以起名的地方都叫标识符。
2.1.2.1定义合法标识符规则:
>由26个英文字母大小写,0-9,_或$组成
>数字不可以开头
>不可使用关键字和保留字,但能包括关键字和保留字。
>Java中严格区分大小写,长度无限制
>标识符不能包含空格
注意:在起名时,为了提高阅读性,要尽量有意义,“见名知意”。
2.1.2.2Java中的名称命名规范
包名: 多单词组成时所有字母都小写:xxxyyyzzz
类名、接口名: 多单词组成,所有单词的首字母大写:XxxYyyZzz
变量名、方法名: 多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
常量名: 所有字母都大写。多单词时每个单词用下划线连接:xxx_YYY_ZZZ
2.2变量
2.2.1数据类型
数据类型: 基本数据类型:数值型:整数类型(byte,short,int,long)
浮点类型(float,double)
字符型(char)
布尔型(boolean)
引用数据类型:类(class)<-------------------------字符串在这里
接口(interface)
数组([ ])
java的整形变量默认为int,声明long型常量须后加“l”或“L”
java的浮点型常量默认为double型。声明float型常量,须后加“f”或“F”
类型 占有存储空间 表数范围
byte 1字节 = 8bit -128~127
short 2字节 -2^15~2^15-1
int 4字节 -2^31~2^31-1
long 8字节 -2^63~2^63-1
单精度float 4字节 -3.403E38~3.403E38
双精度double 8字节 -1.798E308~1.798E308
浮点类型有两种表现形式:
>十进制数形式:如5.12 512.0f .512(必须有小数点)
>科学记数法形式:如:5.12e2 512E2 100E-2
转义字符
\b 退格符
\n 换行符
\r 回车符
\t 制表符
\" 双引符
\' 单引号
\\ 反斜线
注意:Boolean类型:只能取值true或false。不能取null
2.2.2类型转换
自动类型转换:
当容量小的数据类型与容量大的数据类型作运算时,容量小的会自动转换为容量大的数据类型:
char、byte、short==>int==>long==>float==>double
注意:当char/byte/short之间作运算时,默认的结果为int类型
强制类型转换:
当容量大的数据类型转换为容量小的数据类型,要使用强制类型转换符:()
int a;
short b = (short)a;
缺点:导致精度的损失
long l1 = 12345L;
int m1 = (int)l1;//12345
byte by1 = (byte)m1;//57
0000 0000 0000 0000 0011 0000 | 0011 1001
string和基本数据类型之间的运算只能通过:+
2.3进制
二进制:0,1,满2进1,以Ob或OB开头。
十进制:0-9,满10进1。
八进制:0-7,满8进1,以数字0开头表示。
十六进制:0-9及A-F,满16进1,以Ox或OX开头表示,此处的A-F不区分大小写。
正数:三码合一
负数:
原码:二进制编码
反码:除符号位外各个位取反
补码:反码+1
在底层是以补码进行存储
/* 符号位 * 0代表正数 * 1代表负数 * 十进制:57 * 二进制:111001(原码) * * 57/2=28……1 * 28/2=14……0 * 14/2=7……0 * 7/2=3……1 * 3/2=1……1 * 1/2=0……1
2.4运算符
1.测试运算符:
+ - * / % ++ --
取模:%取余数,结果符号取决于被模数。 int i1 = -12 % 5 //-2
前++: 先自增1,后做运算
后++:先做运算,后自增1
2.赋值运算符
+= -= *= /= %=
s+=1 既可以实现运算,也不会改变数据类型
3.比较运算符
== != < > <= >=
instanceof 检查是否是类的对象
4.逻辑运算符
&-逻辑与 &&-短路与 |-逻辑或 ||-短路或 !-逻辑非 ^-逻辑异或
5.位运算符
<< >> >>> | &
交换两个数:
方式一:提供一个临时变量。
int temp = m;
m = n;
n = temp;
方式二:当m和n较大时,有可能出现精度损失
m = m + n;
n = m - n;
m = m - n;
方式三:
m = m ^ n;
n = m ^ n;
m = m ^ n;
int m =10; int n= 20; int z = m^n;//30 二进制运算-异或 int o = z^n;//10 int q = z^o;//20//可用于交换两个数
三目运算符:
定义: >(条件表达式)?表达式1:表达式2:
true:运算后的结果是表达式1
false:运算后的结果是表达式2
运算符优先级:
2.5程序流程控制
顺序结构 分支结构 循环结构
顺序结构:
分支结构: if……else switch
循环结构:while do……while for
注:JDK1.5提供了foreach循环,方便的遍历集合、数组元素
2.6数组
一维数组:
初始化:
静态初始化:names = new String[]{"周爽","Guo","Yulong"};
动态初始化:int[] score = new int[3];
score[0] = 87;
score[1] = 89;
score[2] = 98;
基础数据类型的默认值:
byte、short、int、long创建数组后,默认值为0
float、double创建数组后,默认值为0
char创建数组后,默认值为空格
boolean创建数组后,默认值为false
引用类型的变量构成的数组,默认初始化为null,以String为例。
数组一旦初始化,其长度是不可变的(.length)
一维数组在内存中的结构:
二维数组:
初始化:
int[][] res = new int[5][];
int[][] res1 = new int[][]{};
int[] res2[] = new int[5][];
二维数组在内存中的结构:
数组常见的异常:
1.数组下标越界的异常
java.lang.ArrayIndexOutOfBoundsException: int[] a = new int[5]; for(int i=0;i<=a.length;i++){ System.out.println(a[i]); }
2.空指针异常
java.lang.NullPointerException int[] a = new int[5]; a = null; System.out.println(a[1]);
数组的常用算法:
1.最大值,最小值,总值,平均值
1 @Test 2 public void test1(){ 3 int[] a = new int[10]; 4 Scanner sc = new Scanner(System.in); 5 for(int i=0 ; i < a.length ; i++){ 6 a[i] = sc.nextInt(); 7 } 8 int max = 0; 9 int min = a[0];10 int sum = 0;11 int avg = 0;12 //最大值13 for(int i=0 ; i < a.length ; i++){14 if(a[i] > max){15 max = a[i];16 }17 }18 System.out.println(max);19 //最小值20 for(int i=0 ; i < a.length ; i++){21 if(a[i] < min){22 min = a[i];23 }24 }25 System.out.println(min);26 //总和27 for(int i=0 ; i < a.length ; i++){28 sum += a[i];29 }30 System.out.println(sum);31 //平均值32 System.out.println((sum/a.length));33 }
2.数组复制
1 int[] arry1 = new int[]{1,2,3,4,5,6,7,8,9}; 2 int[] arry2 = new int[arry1.length]; 3 for(int i = 0; i
3.数组元素的反转
1 int[] arry = new int[]{1,2,3,4,5,6,7,8,9};2 for(int i = 0;i
4.遍历
1 int[] arry = new int[]{1,2,3,4,5,6,7,8,9};2 for(int i = 0;i
数组排序:
1.插入序列:
1.1直接插入排序:
个人理解:数组中第一个元素,直接与后面的元素进行比较,将后面比他小的与他交换,这样第一次排序,直接找 出最小的插入到第一个位置,后面的排序依照第一个的操作。
从小到大排序
方法:Arrays.sort(res);
1.2折半插入排序:
1.3Shell排序:
2.交换排序
2.1冒泡排序:
个人理解:
第一次排序,每连续两个元素进行比较,将最大的排到最后,
第二次排序,不用运算最后一个位置的操作,把相对大的排到倒数第二个位置。
……
从小到大排序:
2.2快速排序(分区交换排序)
3.选择排序
3.1简单选择排序
3.2堆排序
4.归并排序
5.基数排序
2.7内存的基本结构
三、面向对象编程
(一)
1.面向对象与面向过程
定义:面向对象是相对于面向过程而言的。面向过程,强调的是功能行为。面向对象,将功能封装进对象,强调具备了功能的对象
一.面向对象的落地法则一:1.设计类,并设计类的成员(成员变量&成员方法)2.通过类,来创建类的对象(也称作类的实例化)3.通过“对象.属性”或“对象.方法”来调用,完成相应功能。
类的实例化在内存的结构
二.创建多个对象,彼此各自拥有一套类的属性,当对其中一个对象的属性进行修改时,不会影响到其他对象的属性值。
三.类的属性(成员变量)成员变量 vs 局部变量相同点:1.遵循变量声明的格式: 数据类型 变量名 = 初始化值 2.都有作用域不同点:1.声明的位置的不同:成员变量:声明在类里,方法外 局部变量:声明在方法方法内,方法的形参部分,代码块内 2.成员变量的修饰符有四个:public private protected 缺省 局部变量没有修饰符,与所在的方法修饰符相同。 3.初始化值:一定有初始化值 成员变量:如果在声明的时候,不显示赋值,那么不同数据类型会有不同的默认初始化值。 byte short int long ==>0 float double ==>0.0 char ==>空格 boolean==>false 引用类型变量 ==>null 局部变量:一定要显式的赋值。(局部变量没有默认初始化值) 4.二者在内存中存放的位置不同:成员变量存在于堆空间中;局部变量存放在栈空间中
四.类的方法1)格式:权限修饰符 返回值类型(void:无返回值/具体的返回值) 方法名(形参){}2)关于返回值类型:有返回值的方法:在方法的最后一定有return + 返回值类型对应的变量
2.类与类之间的关系
1.关联关系:关联体现的是两个类之间语义级别的一种强依赖关系,属于强耦合。这种关系比依赖强、不存在依赖关系的偶然性、关联关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。体现在代码上是,类A中有类B中的成员变量。
class abstract class AbstractGun{ //抽象射击方法 public void shoot(); } class Rifle extends AbstractGun{ //设计射击方法实现 public void shoot(){ System.out.println("步枪射击"); } } class Soldier{ //定义士兵的枪支 private AbstractGun gun; public void setGun(AbstractGun _gun){ this.gun=_gun; } public void killEnemy(abstractGun gun){ System.out.println("士兵开始杀人"); gun.shoot(); } } class client{ public static void main(String [] args){ Soldier solder=new Soldier(); solder.setGun(new Rifle()); solder.killEnemy(); } } //类client与类soldier是依赖关系, //类soldier与类AbstractGun是一种关联关系。Soldier中有AbstractGun的类变量 //类Rifle与类AbstractGun是一种继承关系
2.继承关系(泛化关系)
3.聚合关系:聚合是关联关系的一种特例,体现在整体与部分到的关系,即has-a的关系。此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。比如计算机与CPU、公司与员工的关系等。表现在代码上与关联关系是一致的。
4.实现关系:实现指的是一个类实现interface接口的功能。从类指向实现的接口。
5.依赖关系:类A使用到类B,但这中使用关系是具有偶然性、临时性的,属于弱耦合。 在代码上体现在,类A中含有类B的局部变量
A中方法名(Class B){ }
6.组合关系:组合也是关联关系的一种特例,体现的是一种contains-a的关系,这种关系比耦合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体声明周期结束意味着部分生命周期结束。
3.面向对象思想的概述
类:对一类事物的面熟,是抽象的、概念上的定义
对象:实际存在的该类食物的每个个体,因而也称实例
4.属性:对应类中的成员变量 行为:对应类中成员方法
5.方法的重载overload
要求:1.求同一个类中
2.方法名必须相同
3.方法的参数列表不同(①参数的个数不同②参数的类型不同) 补充:方法的重载与方法的返回值类型没有关系。 参数个数相同,参数的类型相同,但顺序不同依然能构成重载。
public class Person { private String name; private int age; public void eat(){ System.out.println("人吃饭"); } public void eat(String name){ System.out.println(this.name + "吃饭"); } public void eat(String name,int age){ System.out.println(this.name + this.age + "吃饭"); } public void eat(int age,String name){ System.out.println(this.age + this.name + "吃饭"); }}
6.匿名对象
匿名类对象:创建的类的对象是匿名的 1)当我们只需要一次调用类的对象时,我们就可以考虑使用匿名的方式创建类的对象 2)特点:创建的匿名类对象只能调用一次。new XXX({});
public void test1(){ new Son(){ public void show() { // TODO Auto-generated method stub System.out.println("跳舞"); } }.show(); } } class Son{ }
7.可变个数的形参的方法
可变个数的方法1.格式:对于方法的形参:数据类型 ...形参名2.可变个数的形参的方法与同名的方法之间构成重载3.可变个数的形参再调用时,个数从0开始,到无穷个都可以4.使用可变多个形参的方法的形参使用数组是一致的5.若方法中存在可变个数的形参,那么一定要声明在方法参数的最后。6.在一个方法中,最多声明一个可变的形参
@Test public void test2(){ Person p =new Person(); p.eat(1);//吃 p.eat(2,"ss","sw");//qwe p.eat(3,"awq","wd","aw","rt");//ss }class Person{ private String name; private int age; public void eat(int age){ System.out.println("吃"); } public void eat(int age,String name1,String name2){ System.out.println("qwe"); } public void eat(int age,String... name){ System.out.println("ss"); }}
8.方法的参数传递
1.形参:方法声明时,方法小括号内参数 实参:调用方法时,实际传入的参数的值
2.规则:java中的参数传递机制:值传递机制 1)形参是基本数据类型的:将实参的值传递给形参的基本数据类型的变量 2)形参是引用数据类型的:将实参的引用数据类型变量的值(对应的堆空间的对象实体的首地址)传递给形参的引用类型变量
交换数组中指定位置的元素:交换arr数组中索引为i和j的两个元素
3.存储结构
9.类的成分之三:构造器
构造器(constructor 构造方法) contruction CCB ICBC oop
构造器的作用:①创建对象②给创建的对象的属性赋值1.设计类时,若不显式声明类的构造器的话,程序会默认提供一个空参的构造器2.一旦显式的定义类的构造器,那么默认的构造器就不再提供。3.如何声明类的构造器,格式:权限修饰符 类名(形参){}4.类的多个构造器之间构成重载
class Son{ private String name; private int age; private int banji; public Son() {//构造器 super(); // TODO Auto-generated constructor stub } public Son(String name, int age, int banji) { super(); this.name = name; this.age = age; this.banji = banji; } public Son(String name){ super(); this.name = name; } }
10.类对象的赋值
类对象的属性赋值的先后顺序:
1.静态属性初始化
2.静态代码块初始化3.属性的默认初始化4.属性的显式初始化
5.通过构造器给属性初始化
6.通过“对象.方法”的方式给属性赋值
@Test public void test3(){ //5.通过构造器给属性初始化 Son s2 = new Son("小王",9,3); Son s1 = new Son(); //6.通过“对象.方法”的方式给属性赋值 s1.setName("小明"); } class Son{ //1.静态属性初始化 private static String name = "小赵"; //4.属性的显式初始化 private int age = 0 ; //3.属性的默认初始化 private int banji; //2.静态代码块初始化 static{ name = "小张"; } public Son() { super(); // TODO Auto-generated constructor stub } public Son(String name, int age, int banji) { super(); this.name = name; this.age = age; this.banji = banji; } public Son(String name){ super(); this.name = name; } public static String getName() { return name; } public static void setName(String name) { Son.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getBanji() { return banji; } public void setBanji(int banji) { this.banji = banji; } }
(二)面向对象三大特征:
1.封装:
面向对象特性一:封装与隐藏
问题:当创建了类的对象以后,如果直接通过“对象.属性”的方式对相应的对象属性赋值的话, 可能会出现不满足实际情况的意外,我们考虑不让对象来直接作用属性,而是通过“对象.方法” 的形式,来控制对象对属性的访问。实际情况中,对属性的要求就可以通过方法来体现。 解决方法:(封装的思想)①将类的属性私有化。②提供公共的方法(setter&getter)来实现调用。
class Car{ private String name; private int age; private String carname; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getCarname() { return carname; } public void setCarname(String carname) { this.carname = carname; } }
2.继承:
注:toString()方法显示在堆空间的地址值
<1>继承的定义
继承性1.为什么要设计继承性?2.通过"class A extends B"类实现类的继承子类:A 父类(或基类SuperClass):B3.子类继承父类以后,父类中声明的属性、方法,子类就可以获取到 明确:当父类中有私有的属性或方法时,子类同样可以获取得到,只是由于封装性的设计,使得子类不可以直接调用 子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分 extends:子类是对父类功能的“扩展”,明确子类不是父类的子集。4.java类的继承只支持单继承,一个类只能继承一个父类,一个父类可以有多个子类。5.子父类只是相对的概念
class Person{ private String name; private int age; public void eat(){ System.out.println("吃"); } }class Man extends Person{ private String name; private int age; public void sleep(){ System.out.println("睡觉"); }}
<2>方法的重写
方法的重写 -----(方法的重载)修饰符 返回值类型 方法名 (参数列表){}1.前提:有子类继承父类2.子类继承父类以后,若父类的方法对子类不使用,那么子类可以对父类的方法重写(override overwrite)3.重写的规则: 1)要求子类方法的“返回值类型 方法名(参数列表)”与父类的方法一样 2)子类方法的修饰符不能小于父类方法的修饰符 3)若父类方法抛异常,那么子类方法抛的异常类型不能大于父类的 4)子父类的方法必须同为static或同为非static的。
class Person{ private String name; private int age; public void eat(){ System.out.println("吃"); } }class Man extends Person{ private String name; private int age; public void sleep(){ System.out.println("睡觉"); } public void eat(){ System.out.println("男人吃饭"); }}
<3>super
super:可以用来修饰属性、方法、构造器1)当子类与父类中有同名的属性时,可以通过"super.此属性"显式的调用父类中声明的属性。若想调用子类的同名的属性"this.属性"2)当子类重写父类的方法以后,在子类中若想在显式的调用父类的被重写的方法,就需要使用"super.方法"3)super修饰构造器,通过在子类中使用"super(形参列表)"来显式的调用父类中指定的构造器。 >在构造器内部,"super(形参列表)"必须声明在首行。 >在构造器内部,"this(形参列表)"或"super(形参列表)"只能出现一个。 >在构造器中,不显式的调用"this.(形参列表)"或"super(形参列表)"其中任何一个,默认调用的是父类空参的构造器。 建议:设计一个类时,尽量要提供一个空参的构造器。
public void test3(){ Man m1= new Man(); m1.sleep(); }class Person{ String name; int age; public Person() { super(); // TODO Auto-generated constructor stub } public Person(String name, int age) { super(); this.name = name; this.age = age; } public void eat(){ System.out.println("吃"); } }class Man extends Person{ String name; int age; public Man(String name){ super("xia",2);//调用person有参构造器 } public Man(String name, int age) { super(); super.name = name;//调用父类的属性 this.age = age; } public Man() { super(); // TODO Auto-generated constructor stub } public void sleep(){ System.out.println("睡觉"); } public void eat(){ System.out.println("男人吃饭"); } public void read(){ super.eat();//调用父类的方法 }}
<4>子类对象实例化的全过程
3.多态
多态性
1.多态性指的是什么?多态性,可以理解为一个事物的多种表型形态 1)方法的重载和重写2)子类对象的多态性2.子类对象的多态性使用的前提:①要有类的继承②要有子类对父类方法的重写3.程序运行分为编译状态和运行状态对于多态性来说,编译时:"看左边",将此引用变量理解为父类的类型运行时,"看右边",关注于真正对象的实体,子类的对象,那么执行的方法就是子类重写的。子类对象的多态性:父类的引用指向子类对象Person p1 = new Man();(向上转型)虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的时子类重写父类的方法p1.eat();p2.eat();man对象的方法子类特有的方法不能调用,调用的是重写的方法。Person p2 = new Woman();p2.eat();p2.walk();p2.shopping();//错的Woman w = (woman)p2;(向下转型)w.shopping();//对的Woman w1 = (Woman)p1;w1.shopping();//不会报错,运行时,转化异常。instanceof判断引用数据类型格式:对象a instanceof 类A判断a是否是类A的一个实例,是的话,返回true,否则返回false若a是A类的实例,那么a也一定是A类的父类的实例。
其他关键字:
1.this关键字(1,可以用来修饰属性、方法、构造器(2.this理解为当前对象或当前正在创建的对象,比如:this.name,this.show();(3.可以在构造器中通过“this(形参)”的方式显示的调用本类中的其他重载的指定的构造器。 要求:1.在构造器的内部必须声明在首行 2.若一个类中有n个构造器,那么最多有n-1个构造器中使用了this();
2.javabean
JavaBean是一种Java语言写成的可重用组件。标准:1.类是公共的2.有一个无参的公共的构造器3.有属性,且有对应的get,set方法+表示public类型 -表示private类型 #表示protected类型
3.package
package:声明源文件所在的包,写在程序的第一行每“.”一次,表示一层文件目录包名都要小写
4.import
import:1)显式导入指定包下的类或接口2)写在包的声明和源文件之间3)如果需要引入多个类或接口,那么就并列写出4)如果导入的类是java.lang包下的,如:system String Math就不需要显式的声明5)理解.*的概念6)如何处理同名类的导入。如:在util包和sql包下同时存在Date类7)import static 表示导入指定类的static的属性或方法8)导入java.lang.*只能导入lang包下的所有类或接口,不能导入lang的子包下的类或接口
四、高级类属性一:
一.==
1. 基本数据类型,根据基本数据类型的值判断是否相等,相等返回true,反之返回false注:两端数据类型可以不同,在不同的情况下,也可以返回true2.引用数据类型:比较引用类型变量的地址值是否相等。int k = 65;char a = 'A';sysout(k==a);//true
二.equals()
equals():①只能处理引用类型变量②在Object类,发现equals()仍然比较两个引用变量的地址值是否相等java.lang.Object类,是所有根类的父类像String 包装类 File类Date类这些重写Object类的equals()方法,比较是两个对象的。“实体内容”是否完全相同 String str1 = new String("AA"); String str2 = new String("AA"); System.out.println(str1==str2);//false System.out.println(str1.equals(str2));//true
手动修改equals()方法
public boolean equals(Object obj){ if(this == obj){ return true; }else if(obj instanceof MyDate){ MyDate m = (MyDate) obj; return this.day==m.day&&this.month==m.month; }else{ return false; } }
三.toString()方法
toString()方法: * java.lang.Object类的toString()方法的定义如下: * public String toString(){ * return getClass().getName() + "@" + Integer.toHexString(hashCode()); *} *1.当我们打印一个对象的引用时,实际上默认调用的就是这个对象的toString()方法 *2.当我们打印的对象所在的类没有重写Object中的toString()方法时,那么调用的就是Object中定义的toString()方法。 *3.当我们打印的对象所在的类重写了toString()方法时,调用的就是我们自己重写的toString()方法。 *常常我们这样重写,将对象的属性值信息返回。 *像String类,包装类,File类,Date类等,已经实现了Object类中toString()方法的重写。
四.权限修饰符
五.包装类
六.junit
Junit单元测试类1.当前工程下-右键build path-add libraries-Junit42.在主类中,创建一个空参的无返回值的方法,(如:public void test1())用于代码的测试,方法上声明:@test3.导入import org.junit.Test;4.在test1()方法中,进行代码的编写。5.测试:双击方法名,右键run as-junit Test即可
七.包装类和基本数据类型<----->String
1.基本数据类型、包装类---->String类;
调用String类的重载的valueof(XXX x )方法
int i1 = 10; String str1 = i1 + "";//"10"String str2 = String.valueof(i1);
Integer i2 = 20;
2.String类--->基本数据类型、包装类:
调用包装类parseXXx(String str)方法
int i3 = Integer.parseInt(str2);3.JDK5.0以后,自动装箱和拆箱 int i = 10; Integer i1 = i;
五、高级类特性2
<1>static
static修饰变量
static,静态的,可以用来属性、方法、*代码块(或初始化块)、*内部类static修饰属性(类变量):1.由类创建的所有的对象,都共用这一个属性。2.当其中一个对象对此属性进行修改,会导致其他对象对此属性的一个调用。vs实例变量(非static修饰的属性,各个对象各自拥有一套剧本)(随着对象的加载而加载)3.类变量随着类的加载而加载的,而且独一份。4.静态的变量可以直接通过"类.类变量"的形式来调用。5.类变量的加载要早于对象。所以当有对象以后,可以"对象.类变量"使用,但是"类.实例变量"是不行的。6.类变量存在于静态域中。
static修饰方法
static修饰方法(类方法):1.随着类的加载而加载,在内存中也是独一份2.可以直接通过"类.类方法"的方式调用。3.内部可以调用静态的属性或静态的方法,而不能调用非静态的属性或方法。反之,非静态的方法可以调用静态的属性和方法。>静态的方法内是不可以有this或super关键字的。注:静态的结构(static的属性、方法、代码块、内部类)的生命周期要早于非静态的结构,同时被回收也晚于非静态结构
使用静态的变量可以实现"累加"的效果,因为静态的变量在内存中独一份
<2>设计模式
含义:设计模式在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思路(23种设计思路)
单例设计模式
1.解决问题:使得一个类只能够创建一个对象。 2.如何实现?
饿汉式
//饿汉式*只能创建singleton的单个实例Singleton s1 = Singleton.getInstantce();Singleton s2 = Singleton.getInstantce();s1==s2//trues1与s2只想锥空间的一个区域class Singleton{1.私有化构造器,使得在类的外部不能够调用此构造器private Singleton(){}2.在类的内部创建一个类实例private static Singleton instance = new Singleton();3.私有化此对象,通过公共的方法来调用4.此公共的方法,只能通过类来调用,因为设置为static的,同时类的实例也必须为static声明的public static Singleton getInstance(){ return isntance;}}
懒汉式
//懒汉式:可能存在线程安全问题只用创建一个对象*只能创建singleton的单个实例Singleton s1 = Singleton.getInstantce();Singleton s2 = Singleton.getInstantce();s1==s2//trues1与s2只想锥空间的一个区域class Singleton{1.私有化构造器,使得在类的外部不能够调用此构造器private Singleton(){}2.在类的内部创建一个类实例private static Singleton instance = null;3.私有化此对象,通过公共的方法来调用4.此公共的方法,只能通过类来调用,因为设置为static的,同时类的实例也必须为static声明的public static Singleton getInstance(){ if(instance ==null){ isntance =new Singleton(); } return instance;}}
模板方法设计模式
模板方法设计模式解决问题:一部分确定,一部分不确定。
<3>类的第四个成员:初始化块(代码块)
类的第四个成员:初始化块(或代码块)1.代码块如果有修饰的话,那么只能使用static。2.分类静态代码块:1.里面可以输出语句2.随着类的加载而加载,而且只被加载一次3.多个静态代码块之间按照顺序结构执行4.静态代码块的执行要早于非静态代码块的执行5.静态的代码块种只能执行静态的结构(类属性.类方法)非静态代码块:1.可以对类的属性进行初始化操作2.里面可以有输出语句3.一个类中可以有多个非静态的代码块,多个代码块之间按照顺序结构执行4.每创建一个类的对象,非静态代码块就加载一次。5.非静态代码块的执行早于构造器属性:初始化块{ }static{ }构造器
<4>final
final:最终的,可以用来修饰类、属性、方法1.final修饰类:这个类就不能继承。如:String类,StringBuffer类,System类2,final修饰方法:不能被重写。如:Object类的getClass()3.final修饰属性,此属性就是一个常量,一旦初始化后,不可在被赋值。习惯上,常量用大写字符表示。此常量在哪里复制:①此常量不饿能使用默认初始化②可以显式的赋值,代码块,构造器。变量用static final修饰:全局变量
<5>abstract抽象
abstract:抽象的,可以用来修饰类、方法1.abstract修饰类:抽象类1)不可被实例化2)抽象类有构造器(凡是类都有构造器)3)抽象方法所在的类,一定是抽象类。4)抽象类中可以没有抽象方法。2.abstract修饰方法:抽象方法1)格式:没有方法体,包括{},如:public abstract void eat();2)抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写此抽象方法。3)若子类继承抽象类,并重写了所有抽象方法,则此类是一个 "实体类",即可以实例化4)若子类继承抽象类,没有重写所有的抽象方法,意味着此类中仍有抽象方法,则此类必须声明为抽象的。
abstract 不能用来修饰属性,构造器,private,final,static
<6>interface
接口(interface)是与类并行的一个概念1.接口可以看作是一个特殊的抽象类。是常量与抽象方法的一个集合,不能包含变量、一般的方法。2.接口师妹有构造器的3.接口定义的就是一种功能。此功能可以被类所实现(implements).比如:class CC implements AA4.实现接口的类,必须要重写其中的所有的抽象方法,方可实例化,若没有重写所有的抽象方法,则此类仍为一个抽象类。5.类可以实现多个接口。--------java继承是单继承的6.接口和接口之间也是继承关系,而且实现多继承interface AA{ 常量:所有的常量都用public static final 修饰 int i = 12; boolean FLAG = false; 抽象方法:所有的都用public abstract 修饰 void method1(); void method2();}
<7>接口的用法总结
接口用法总结1.通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。2.通过接口可以指明多个类需要实现的方法,一般用于定义对象的扩张功能。3.接口主要用于定义规范。解除耦合关系
<8>工厂方法FactoryMethod
工厂方法(FactoryMethod)概述:定义一个用于创建对象的接口,让子类决定实例化的那一个类。FactoryMethod是一个类的实例化延迟到其子类。适用性:1.当一个类不知道它所必须创建的对象的类的时候2.当一个类希望由它的子类来制定他所创建的对象的时候3.当类将创建对象的职责委托给多个帮助子类的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
<9>接口的应用:代理模式
<10>第五个成员:内部类
含义:
类的第五个成员:内部类1.相当于说,我们可以在类的内部在定义类。外面的类:外部类 里面定义的类:内部类2.内部类的分类:成员内部类(声明在类内部且方法外的) vs 局部内部类(声明在类的方法里)3.成员内部类: 3.1是外部类的一个成员:①可以有修饰符(4个)②static final?可以调用外部类的属性方法 3.2具体类的特点:①abstract②还可以在其内部定义属性、方法、构造器4.局部内部类5.关于内部类:①如何创建成员内部的对象②如何区分调用内部类、外部类的变量?局部内部类
成员内部类
成员内部类创建静态内部类的对象,可以直接通过外部类调用静态内部类的构造器Person.Dog d = new Person.Dog();创建非静态内部类的对象,必须像创建外部类的对象,通过外部类的对象调用内部类的构造器Person p = new Person();Person.Bird b = p.new Bird();可以在内部类调用外部类的方法main{ Person p = new Person(); Person.Bird b = p.new Bird(); b.setName("杜鹃");}class Person{ String name = "韩梅梅"; class Bird{ String name = "黄丽"; public void setName(String name){ sysout(name);//杜鹃 sysout(this.name);//黄鹂 sysout(Person.this.name);//韩梅梅 } }}
局部内部类
局部内部类class OuterClass{ public void method1(){ class InnerClass{ } } 方式一: public Comparable getCompararble(){ 1.创建一个实现Comparable接口的类:局部内部类 class MyComparable implements Comparable{ 重写方法(); } //返回一个实现类对象 return new MyComparable(); } 方式二: public Comparable getCompararble(){ //2.返回一个实现Comparable接口的匿名内部类的对象 return new Comparable(){ 重写方法(); } }}
六、异常处理
体系结构
异常
java.lang.Throwable------Error:错误,程序中不进行运行。------Exception:异常,要求在编写程序时,就要考虑到对这些异常的处理分类:编译时异常和运行时异常编译时异常:在编译期间会出现的异常(执行javac.exe命令时,出项异常)运行时异常:在运行期间出现的异常(执行java.exe命令时,出现异常)当执行一个程序时,如果出现异常,那么异常之后的代码就不在执行常见的运行时异常---RunTimeException1.数组下标越界的异常:ArrayIndexOutOfBoundsException2.算术异常:ArithmeticException3.类型转换异常:ClassCastException4.空指针异常:NullPointerException
Exception异常的处理
方式一:try-catch
如何处理Exception的异常
Java提供的是异常处理的抓抛模型1."抛":当我们执行代码时,一旦出现异常,就会在异常的代码处生成一个对应的异常类型的对象,并将此对象抛出。(自动抛出&手动抛出) >一旦抛出此异常类的对象,那么程序就终止执行 >此异常类的对象抛给方法的调用者2."抓":抓住上一步抛出来的异常类的对象。如何抓?即为异常处理的方式 java提供了两种方式用来处理一个异常类的对象 处理的方式一: try{ //可能出现异常的代码 }catch(Exception e1){ //处理的方式一 }catch(Exception e2){ //处理的方式二 }finally{ //一定要执行的代码 }注:1.try内声明的变量,类似于局部变量,出了try{}语句,就不能被调用 2.finally是可选的。 3.catch语句内部是对异常对象的处理: >getMessage(); //获取message > printStackTrace();//打印异常信息 4.可以有多个catch语句,try中抛出的异常类对象从上往下去匹配catch中的异常类的类型,一旦满足就执行catch中的代码,执行完,就跳过其后的多条catch语句。 5.如果异常处理了,那么其后的代码继续执行。 6.若catch中多个异常类型是"并列"关系,孰上孰下都可以。 若catch中多个异常类型是"包含"关系,须将子类放在父类的上面,进行处理,否则报错。 7.finally中存放的是一定会被执行的代码,不管try中、catch中是否仍有异常未处理,以及是否有return语句 8.try-catch是可以嵌套的三.对于运行时的异常来说,可以不显式的进行处理, 对于编译时异常来说,必须要显式的继续处理
方式二throw:
异常处理的方式二:在方法的声明处,显式的抛出该异常对象的类型格式:如 public static void method2() throws FileNotFoundException,IOException{}当在此方法内部出现异常的时候,会抛出一个异常类的对象,抛给方法额调用者。异常的对象可以逐层向上抛,直至main中。当然向上抛的过程中,可以在通过try-catch-finally进行处理
手动抛出异常
手动抛出一个异常:抛出异常类型,若是RuntimeException,可以不显式的处理若是一个Exception,必须显式的处理throw new RunTimeException("xxxxx");
自定义一个异常类
如何自定义一个异常类1.自定义的异常类继承现有的异常类2.提供一个序列号,提供几个重载的构造器public class MyException extends Exception{ static final long serialVersionUID = -70348975L; public MyException(){ } public MyException(String msg){ super(msg); }}
抛异常的方法的重写规则
子类重写父类的方法,其抛出的异常类型只能是被重写的方法的异常类的子类或异常类型一样。A a = new B();try{ a.method1();}catch(IOException e){ e.printStackTrace(); }class A{ public void method1() throws IOException{ }}class B extends A { public void method1() throws FileNotFoundException{ }}
七、java集合
集合体系结构
collection
方法:
Collection coll = new ArrayList();1.size():返回集合中元素的个数2.add(Object obj):向集合中添加一个元素3.addAll(Collection coll):将形参coll中包含的所有元素添加到当前集合中4.isEmpty():判断集合是否为空5.clear():清空集合元素6.sysout(coll):查看几何中的元素7.Collection coll1 = Arrays.asList(1,2,3):声明是直接加进元素8.contains(Object obj):判断几何中是否包含指定的obj元素。如果包含,返回true,反之,返回false判断的依据,根据元素所在的类的equals()方法进行判断明确:如果存入集合中的元素是自定义类的对象。要求:自定义类要重写equals()方法9.containsAll(Collection coll):判断当前集合中是否包含coll中的所有元素10.retainAll(Collection coll1):求当前集合与coll的共有的元素,返回给当前集合11.remove(Object obj):删除集合中的obj元素。若删除成功,返回true,否则返回false12.removeAll(coll1):从当前集合中删除包含在coll中的元素13.equals(Object obj):比较两个集合中的所有元素是否相同14.hashCode():集合的hash值,堆空间放在那里15.toArray():将集合转化为数组16.iterator():返回一个Iterator接口实现类的对象,进而实现集合的遍历。Iterator iterator = coll.iterator();whille(iterator.hasNext())sysout(iterator.next());//输出一个
collection子类:
------->List
ArrayList:List的主要实现方法List中相对于Collection,新增加的方法1.void add(int index,Object obj):在指定的索引位置index添加元素ele2.boolean addAll(int index,Collection eles)3.Object get(int index):获取指定索引的元素4.Object remove(int index):删除指定索引位置的元素5.Object set(int index,Object ele):设置指定索引位置的元素ele6.List subList(int fromIndex,int toIndex):返回从formIndex到toIndex结束的一个子list集合(左闭右开:包括左边不含右边)7.int indexOf(Object obj)返回obj在集合中首次出现的位置,没有返回-18.int lastIndexOf(Object obj)返回obj在集合中最后一次出现的位置,没有返回-1List常用的方法:增(add(Object obj))删(remove)改(set(int index,Object ele))查get(int index)插(add(int index,Object obj))长度(size())
--------->Set子类:
--------------------->HashSet:
Set:存储的元素是无序的,不可重复的1.无序性:无序性!=随机性。真正的无序性,指的是元素在底层储存的位置是无序的。2.不可重复性:当向Set中添加进相同的元素的时候,后面的这个不能添加进去。说明:要求添加进Set中的元素所在的类,一定要重写equals()和hashCode()方法。进而保证Set中元素的不可重复性。Set中的元素如何存储的呐?使用啦哈希算法。当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算此对象的哈希值, 此哈希值决定了此对象在Set中存储位置。若此位置之前没有对象储存,则这个对象直接存 储到此位置。位置已有对象存储,再通过equals()比较这两个对象是否相同,如果相同, 后一个对象就不能再添加进来,万一返回false呐,都存储。(不建议如此)>要求:hashCode()方法要与equals()方法一致
---------------------->LinkedHashSet:
LinkHashSet:使用链表维护一个添加进集合中的顺序,导致当我们遍历LinkedHashSet集合元素时,是按照添加进去的顺序遍历的LinkedHashSet插入性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能
----------------------->TreeSet
自然排序---------自然排序接口Comparable
TreeSet:1.向TreeSet中添加的元素必须是同一个类的2.可以按照添加进集合中的元素的指定顺序遍历。像String,包装类等默认按照从小到大的顺序遍历。3.当向TreeSet中添加自定义类的对象时,有两种排序方法:①自然排序②定制排序4.自然顺序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)的抽象方法在此方法中,指明按照自定义类的哪个属性进行排序5.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象此属性值相同。但是程序会认为这两个对象是相同的,进而后一个对象是不能添加进来的>compareTo()与hashCode()以及equals()三者保持一致public int compareTo(Object obj){ if(o instanceof Person){ Person p = (Person)o; int i = this.age.compareTo(p.age); if(i == 0){ return this.name.compareTo(p.name); }else{ return i; } } return 0;} 1.要求添加TressSet中的元素所在的类implements Comparable接口 2.重写compareTo(object obj),在此方法内指明按照元素的哪个属性进行排序 3.向TreeSet中添加元素即可,若不实现此接口,会报运行时异常
定制排序----------定制排序接口Comparator
定制排序:>compare()与hashCode()以及equals()三者保持一致1.创建一个实现了Comarator接口的类对象Comparator com = new Comparator(){ 向TreeSet中添加Customer类的对象,在此compare()方法中,指明是按照Customer的哪个属性排序的 public int compare(Object o1,Object o2){ if(o1 isntanceof Customer && o2 isntanceof Customer){ Customer c1 = (Customer)o1; Customer c2 = (Customer)o2; int i = c1.getId().compareTo(c2.getId()) ; if(i==0){ return c1.getName().compareTo(c2.getName()); } return i; } return 0 } };2.将此对象作为形参传递给TreeSet的构造器中TreeSet set = new TreeSet(com);3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象set.add(new Customer("AA",1003));set.add(new Customer("BB",1002)); 1.创建一个实现Comparator接口的实现类的对象,在实现类中重写Comparator的compare(Object o1,Object o2)方法 2.在此compare()方法中指明按照元素所在类的哪个属性进行排序 3.将此实现Comparator接口的实现类的对象作为形参传递给TreeSet的构造器中 4.向TreeSet中添加元素即可。若不实现此接口,会报与运行时异常
遍历集合
遍历集合:1.使用迭代器iterator实现集合的遍历Iterator iterator = coll.iterator();whille(iterator.hasNext())sysout(iterator.next());//输出一个2.使用增强for循环实现集合的遍历for(Object i : coll){ sysout(i);}
Map
Map接口1.Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value2.Map中的key和value都可以时任何引用类型的数据3.Map中的key用Set来存放,不允许重复,即同一个Map对象所对应的类,须重写hashCode()和equals()方法4.常用String类作为Map的"键"。5.key与value之间存在单向一对一关系,即通过指定的key总能找到唯一的、确定的value
Map接口体系的继承树
遍历Key-Value
遍历key-value对方式一:Set set1 = map.keySet();for(Object obj : set1){ sysout(obj + "--->" + map.get(obj));}方式二:Set set2 = map.entrySet();for(Object obj : set2){ Map.Entry entry = (Map.Entry)obj; sysout(entry);/ sysout(entry.getKey() + "--->" + entry.getValue())} key是不可重复的,使用Set存放,value可以重复的,使用Collection来存放的, 一个key-value对构成一个entry(Map.Entry),entry使用Set来存放
Map分类
HashMap:
一.HashMap:key是用Set来存放的,不可重复。value是用Collection来存放的,可重复一个key-value对,是一个Entry。所有的Entry是用Set存放的,也是不可重复的。二.向HashMap中添加元素时,会调用key所在类的equals()方法,判断两个key是否相同,若相同,则只能添加进去后添加的那个元素1.Object put(Object key,Object value):向Map中添加一个元素,可以存null。2.int size():返回集合的长度3.Object remove(Object obj):按照指定的key删除此key-value4.void putAll(Map t):放入一个Map集合5.void clear():清空6.Object get(Object key):获取指定key的value值,若无此key 7.boolean containKey(Object key):是否有这个key8.boolean containsValue(Object value)是否有这个值9.boolean isEmpty()是否为空10.boolean equals(Object obj)是否跟另一个Map集合相同 key 不重复 比较 :重写equals()和hashCode()方法 value 可重复 比较:重写equals()方法
LinkedHashMap
LinkedHashMap:使用链表维护添加进Map中的顺序,故遍历Map时,是按添加的顺序遍历的
TreeMap
按照添加进Map中的元素的key的指定属性进行排序。要求:key必须是同一个类的对象 自然排序vs自制排序
Hashtable
古老的实现类,线程安全,不建议使用Properties 常用来处理属性文件,键和值都是String类型的
Collections工具类
reverse(List)反转List中元素的顺序shuffle(List):对List集合元素进行随机排序sort(List):根据元素的自然顺序对指定List集合元素按升序排序sort(List,Comparator):根据指定的Comparator产生的顺序对List集合元素进行排序swap(List,int ,int):将指定list集合中的i处元素进行交换Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素Object max(Collection,Comparator):根据Comparator指定的顺序,返回给定集合中的最大元素Object min(Collection)根据元素的自然顺序,返回给定集合中的最小元素Object min(Collection,Comparator):根据Comparator指定的顺序,返回给定集合中的最小元素int frequency(Collection,Object):返回指定集合中指定元素的出现次数void copy(List dest,List src):将src中的内容复制到dest中boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换List的旧值对象List list1 = Arrays.asList(new Object[list.size()]);Collections.copy(list1,list);sysout(list);通过如下的方法保证list线程的安全性List list2 = Collections.synchronizedList(list);
八、泛型
1.在集合中使用泛型
Map Mapmap = new HashMap<>();map.put("AA",33); ListList list = new ArrayList ()list.add(78);Iterator it = list.iterator();while(it.hasNext()){ sysout(it.next());} entry Set > set = map.entrySet(); for(Map.Entry o : set){ sysout(o.getKey() + "--->" +o.getValue()); }
2.自定义泛型类、泛型接口、泛型方法
1.当实例化泛型类的对象时,指明泛型的类型 指明之后,对应的类中所有使用泛型的位置,都变为实例化中指定的泛型的类型2.如果我们自定义了泛型类,但是在实例化时没有使用,那么默认类型是Object类的 继承泛型类或泛型接口时,可以指明泛型的类型 private T t; Listlist = new ArrayList<>();自定义泛型类的使用:Order order = new Order ();声明泛型方法public E getE(E e){ return e;}//当通过对象调泛型方法时,指明泛型方法的类型调用泛型方法Integer i = order.getE(34);Double d= order.getE(2.3);
自定义泛型类
泛型类注意点
泛型类1.静态方法中不能使用类的泛型2.如果泛型类是一个接口或抽象类,则不能创建泛型类的对象。3.不能在catch中使用泛型4.从泛型类派生子类,泛型类型需具体化把一个集合中的内容限制为一个特定的数据类型。
3.泛型与继承的关系
4.通配符
? extends A:可以存放A及其子类
? super A:可以存放A及其父类
注意:
九、枚举&注解
枚举:
自定义枚举类
//枚举类class Season{ //1.提供类的属性,声明为private final private final String seasonName; private final String seasonDesc; //2.声明为final的属性,在构造器中初始化 private Season(String seasonName,String seasonDesc){ this.seasonName = seasonName; this.seasonDesc = seasonDesc; } //3.通过公共的方法来调用属性 public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } //4.创建枚举类的对象:将类的对象声明public static final public static final Season SPRING = new Season("spring","春暖花开"); public static final Season SUMMER = new Season("summer","夏日炎炎"); public static final Season AUTOMN = new Season("autumn","秋高气爽"); public static final Season WINTER = new Season("winter","白雪皑皑"); @Override public String toString() { return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]"; } public void show(){ System.out.println("这是一个季节"); }
enum关键字定义枚举类
常用的方法:value() valueOf(String name)
1.values() Season1[] season = Season1.values(); for(int i = 0;i < season.length;i++){ System.out.println(season[i]); } 2.valueOf(String name):要求传入的形参name是枚举类对象的名字 String str = "SPRING"; Season1 sea = Season1.valueOf(str);
让枚举类是实现接口:可以让不同的枚举类的对象调用被重写的抽象方法,执行的效果不同
enum Season extends ss{ SPRING("spring","春暖花开"){ public void show(){ System.out.println("春天"); } }, SUMMER("summer","夏日炎炎"){ public void show(){ System.out.println("夏天"); } }, AUTOMN("autumn","秋高气爽"){ public void show(){ System.out.println("秋天"); } }, WINTER("winter","白雪皑皑"){ public void show(){ System.out.println("冬天"); } }; private String seasonName; private String seasonDesc; private Season(String seasonName,String seasonDesc){ this.seasonName = seasonName; this.seasonDesc = seasonDesc; } public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } public String toString() { return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]"; }
注解annotation
1.JDK内置的基本注解类型(3个)
@Override:限定重写父类的方法,该注释只能用于方法
@Deprecated:用于表示某个程序元素(类,方法等)已过时
@SuppressWarnings:抑制编译器警告
2.自定义注解类型
public @interface XX{ String value() default "hellow";}@XX(value = "xxx")
3.对注解进行注解(4个)(原注解)
4.利用反射获取注解信息(在反射部分涉及)
十、IO
File类
java.io.File类1.凡是与输入、输出相关的类、接口等都定义在java.io包下2.File是一个类,可以有构造器创建其对象。此对象对应着一个文件或文件目录3.File类对象是与平台无关的4.File中的方法,仅涉及到如何创建、删除、重命名等等,只要涉及文件内容的,File无能为力。必须有IO流来完成5.File类的对象常作为IO流的具体类的构造器的形参。路径:绝对路径:包括盘符在内的完整的文件路径相对路径:在当前文件目录下的文件的路径
File方法
getName()//获取文件名getPath()//获取文件路径getAbsoluteFile()//获取绝对文件名getParent()//获取上一层的文件路径//相对路径时nullgetAbsolutePath()//获取绝对路径renameTo(File newName)//重命名file1.renameTo(file2)//file1重命名为file2.要求file文件一定存在,file2一定不存在exists()//文件存在canWrite()//文件可写canRead()//文件可读isFile()//是文件吗isDirectory()//是文件目录lastModfied()//最后修改时间length()//内容长度sysout(new Date(file1.lastModified()));createNewFile()delete()mkDir():创建一个文件目录,只有在上层文件目录存在的情况下,才能创建mkDirs():创建一个文件目录,若上层文件目录不存在,一并创建。list() :得到文件目录的内容,用字符串数组接收listFiles():得到文件目录的内容,用文件数组接收。
IO的体系
流
FileInputStream
//read()@Test public void test1(){ FileInputStream fis = null; try { File file1 = new File("g:/IO/hello2.txt"); fis = new FileInputStream(file1); int b = fis.read(); while(b!=-1){ System.out.print((char)b); b = fis.read(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(fis != null){ try { fis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //read(byte[] byte) @Test public void test2(){ FileInputStream fis = null; try { File file2 = new File("g:/IO/hello2.txt"); fis = new FileInputStream(file2); byte[] b = new byte[5]; int len ; while((len = fis.read(b))!= -1){ for(int i= 0 ;i
FileOutputStream
输出的物理文件可以不存在,当执行过程中,若不存在,会自动的创建,若存在,会将原有的文件覆盖
@Test public void test3(){ File file3 = new File("g:/IO/hello3.txt"); FileOutputStream fos = null; try{ fos = new FileOutputStream(file3); fos.write(new String("I love myself!").getBytes()); }catch(Exception e){ e.printStackTrace(); }finally{ if(fos!=null){ try { fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
FileReaderFileWriter
@Test public void test5(){ FileReader fr = null; FileWriter fw = null; try { File file1 = new File("C:\\Users\\dell\\Desktop\\新建文件夹\\java基础.txt"); File file2 = new File("C:\\Users\\dell\\Desktop\\新建文件夹\\111.txt"); fr = new FileReader(file1); fw = new FileWriter(file2); int len; char[] c = new char[1000]; while((len=fr.read(c))!=-1){ fw.write(c, 0, len); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(fr!=null){ try { fr.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(fw!=null){ try { fw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
BufferedInputStream/BufferedOutputStream
@Test public void test6(){ FileInputStream fis = null; FileOutputStream fos = null; BufferedInputStream bis = null; BufferedOutputStream bos = null; try { File file1 = new File("D:\\百度网盘下载\\java\\第10章:IO(day15-day16)\\day15\\day15_04IO流概述.wmv"); File file2 = new File("D:\\百度网盘下载\\java\\第10章:IO(day15-day16)\\day15\\1.wmv"); fis = new FileInputStream(file1); fos = new FileOutputStream(file2); bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); int len; byte[] b = new byte[1024]; while((len = bis.read(b))!= -1){ bos.write(b, 0, len); bos.flush(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(bis!= null){ try { bis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(bos!=null){ try { bos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
BufferedWriter/BufferedReader
@Test public void test7(){ BufferedWriter bw = null; BufferedReader br = null; try { File file1 = new File(""); File file2 = new File(""); FileReader fr = new FileReader(file1); FileWriter fw = new FileWriter(file2); br = new BufferedReader(fr); bw = new BufferedWriter(fw); String str; while((str = br.readLine())!= null){ bw.write(str); bw.newLine();//换行 bw.flush(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(bw!=null){ try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(br!=null){ try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
转换流:
InputStreamReader / OutputStreamWriter(前提:数据是文本文件)
/*如何实现字节流与字符流之间的转换: * 转换流:InputStreamReader OutputStreamWriter * 编码:字符串 ---->字符数组 * 解码:字符数组--->字符串 */ @Test public void test8(){ BufferedReader br = null; BufferedWriter bw = null; try { File file1 = new File(""); File file2 = new File(""); FileInputStream fis = new FileInputStream(file1); FileOutputStream fos = new FileOutputStream(file2); InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); br = new BufferedReader(isr); bw = new BufferedWriter(osw); String str; while((str = br.readLine())!=null){ bw.write(str); bw.newLine(); bw.flush(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(bw!=null){ try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(br!=null){ try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
标准的输入输出流:
标准的输出流:System.out 标准的输入流:System.in str.toUpperCase();小写变大写
注:使用FileReader、FileWriter 可以实现文本文件的复制
对于非文本文件(视频文件、音频文件、图片),只能使用字节流
打印流:
打印流:字节流:PrintStream 字符流:PrintWriter//创建打印输出流,设置为自动刷新模式(写入换行符或字节'\n'时都会刷新输出缓存区) if(ps != null){ //把标准输出流(控制台输出)改成文件 System.setOut(ps); }
数据流:
数据流:用来处理基本数据类型、String、字节数组的数据:DataInputStream DataOutputStream
对象流:
要实现序列化的类:1.要求此类是可序列化的,实现Serializable接口 2.要求类的属性同样的要实现Serializable接口 3.提供一个版本号,private static fianl long serialVersionUID 4.使用static 或 transient 修饰的属性,不可实现序列化 对象的序列化过程,将内存中的对象通过ObjectOutputStream转换为二进制流,存储到硬盘文件中 对象的反序列化过程,将二进制流通过ObjectInputStream转换为内存中的对象。
RandomAccessFile:
/* * RandomAccessFile:支持随机访问 * 1.即可以充当一个输入流,又可以充当一个输出流 * 2.支持从文件的开头读取、写入 * 3.支持从任意位置的读入、写入(插入) */ @Test public void testRandomAccess(){ RandomAccessFile raf1 = null; RandomAccessFile raf2 = null; try { raf1 = new RandomAccessFile(new File("hello.txt"),"r"); raf2 = new RandomAccessFile(new File("hello1.txt"),"rw"); byte[] b = new byte[5]; int len; while((len = raf1.read(b)) != -1){ raf2.write(b,0, len); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(raf1 != null){ try { raf1.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(raf2!=null){ try { raf2.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /* * 实现文件指定位置插入数据 */ @Test public void test2(){ RandomAccessFile raf = null; try { raf = new RandomAccessFile(new File("hello1.txt"), "rw"); raf.seek(4);//把指针位置移到第4个位置 byte[] b = new byte[10]; int len; StringBuffer sb = new StringBuffer(); while((len = raf.read(b))!=-1){ sb.append(new String(b,0,len));//把文件中当前指针位置后面的数据存到StringBuffer } raf.seek(4); raf.write("YHS".getBytes()); raf.write(sb.toString().getBytes()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(raf!=null){ try { raf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
十一、多线程
十二、java常用类
十三、java反射机制
十四、网络编程