JAVA_HOME=jdk安装目录
Path:%JAVA_HOME%\bin;…
CLASSPATH=.;(系统类默认加载路径)
文件后缀名: [ClassName].java
文件名需要和内容中 public class ClassName
1.source file:
1).end with .java
2).有且只能有一个顶级的public class/interface,如果存在public声明的类/interface,那么文件的名字一定要和public class/interface后边跟的名字保持一致
2.package
1.如果存在的话必须位于源文件内容的第一行
2.在运行有package定义的java类的时候,类名必须指定为packageName+className
3.package存在的意义:
为了将具有类似功能或意义的类/接口组织在一起。
避免命名冲突
3.import:导入使用到的其他的类文件(除了当前package下边的以及java.lang.*);
.java[main方法]---->编译javac--->.class字节码文件---->运行java../../
javac -d 存放.class文件的路径 源文件
java -cp .class文件的路径 类名
1.编译:
javac [-d pathName] javasorce -d pathName : 将源文件编译过后生成的.class文件存放在-d选项所制定的pathName路径下。
2.运行:
java [-cp path] className -cp path : -classpath ,临时改变classpath环境变量的值(指定要执行的类 的.class文件的搜索路径)
3.打包
切换到bin目录下 jar -cvf ./hello.jar *
jar包
1.package
2.import
3.class/interface
java类加载(双亲委托机制):
1.启动类加载:jre/lib/rt.jar
2.扩展类加载:jre/lib/ext/*.jar
3.系统类加载:classpath
java class…
java -cp . HelloWorld
com.briup.test.HelloWorld2
4.网络类加载
效率,[可读性]
1/3以上
1.单行注释
//注释内容
2.多行注释:
/comment内容/
3.文档注释:
/**
注释的内容
@param 用来对参数进行描述
@author 作者信息(javadoc -author)
@version 当前版本信息(javadoc -version)
@since 从哪个版本开始
@return 返回值的信息
@see @link
@throws
*/
1.java语句的结束,必须使用;作为标识
2.{}用来组织java语句形成代码块(例如:类体,方法体,代码块),在java中不存在孤立的代码
3.空白(空格,制表符,换行符。。。)可以相互随意替换(无关)。
分隔符:java语言中的分号
(;)
、花括号({})、方括号([])、圆括号()、空格(space,Tab,enter)、圆点(.)都具有特殊的分隔作用,统称为分隔符。
1.分号
java中对语句的分隔不是使用回车,而是使用分号(;)作为语句的分隔,每个java语句使用分号作为结尾,java程序允许一行书写多个语句,以分号隔开即可[可读性差],一个语句也可以跨多行,只要最终结束的时候使用分号结束即可。
字符串、变量名不能跨越多行。
2.花括号
花括号的作用就是定义一个代码块,一个代码块指的就是"{“和”}"所包含的一段代码,在java中,类定义部分必须放在一个代码块里,方法体部分也必须放在一个代码块里,条件语句中的条件执行体和循环语句中的循环体通常也放在代码块里。
3.方括号
紧跟数组变量名,访问数组元素,方括号中指定希望访问的数据元素的索引。
4.圆括号
功能丰富,定义方法时必须使用圆括号来包含所有的形参声明,调用方法时也必须使用圆括号来传入实参值,在表达式中括起某部分改变计算优先级,还可以作为强制类型转换的运算符。
5.空格
空格可以几乎出现在任何地方,可以出现任意多个,但不要使用空格试图把一个变量名分隔开成两个,java中的空格包含空格符(space),制表符(Tab),回车(Ebter)等,合理使用空格缩进java代码,提高程序可读性
6.圆点
通常作为类/对象和其中成员如属性,方法等之间的分隔符,表示调用某个类或者某个实例的属性或者方法。
标识符:在java中定义的一些用来表示变量名,对象名,方法名,类名,接口名,常量名,包名等的一些(名字)标识。
命名规则:
1.名字必须以字母,_或者$开头,后边可以跟任意字母数字_或者$
2.严格区分大小写。(大小写敏感) Name name
3.不能包含空格
4.不能是java中的关键字或者是保留字
关键字
保留字(goto,const)
推荐命名规则:
1.变量名,方法名首字母小写,如果由多个单词组成,那么除了首个单词的首字母小写之外,其他单词的首字母都大写。
myName , getName()...
2.类名,接口名如果有多个单词组成,那么每个单词的首字母全部大写:
HelloWorld BirdAction
3.常量名字,要求全大写,多个单词之间一般使用_分割
MAX_VALUE MIN_VALUE
4.包名域名倒过来的写法。
5.所有名字表意性一定要强。
java是一门强类型语言,强类型包含两方面的含义:
1.所有的变量必须先声明,后使用
2.之ID年各类型的变量只能接受类型与之匹配的值。
强类型语言可以在编译过程中发现源代码的错误,从而保证程序更加健壮。
java语言提供了丰富的【基本数据类型】,大致分为两类:数值类型和布尔类型,其中数值类型包括整型、字符型和浮点型
强类型语言,意思是每个变量和表达式都有一个在编译时就确定的类型,所有的变量必须显示声明类型,然后使用,类型限制了一个变量能被赋的值,限制了一个表达式可以的值,限制了在这些值上可以进行的操作,并确定了这些操作的含义。
java语言支持的类型分为两类:基本数据类型和引用类型
基本类型包括boolean类型和数值类型,数值类型包括整数类型、字符类型和浮点类型。整数类型包括byte,short,int,long,char[字符型也是一种正数类型],浮点型包括float和double
引用类型包括类、接口和数组类型、null,所谓引用数据类型就是对一个对象的引用,对象包括实例和数组两种,实际上引用类型变量就是一个指针,只是java语言里不再使用指针这个说法,空引用(null)可以转换为任何引用类型,可以认为null只是引用类型的一个特殊直接量
基本数据类型(八种):
1.布尔类型(boolean)
1.在java中只有两个字面值true,false
使用:
2.字符类型(char):表示单个字符,必须使用单引号括起来
1.无符号16位的值来表示字符类型。
2.字面值使用''括起来
char c ='中';
char c = 'c';
char c = '\u4e2d';//使用Unicode值表示字符型常量
char c = 97;
\:转义字符
char c = '\n';
char c = "\t";
3.数字类型(byte,short,int,long,float,double)
3.1整数类型:byte,short,int ,long
note:1.都可以使用八进制(前缀0),十进制,十六进制(前缀为0x)表示
2.默认的整数类型为int
3.在long类型的额值之后加后缀l或者L
1.byte:占8位,-128(-2^7)~127(2^7-1)
2.short:占用16位,-32768(-2^15)~32767(2^15-1)
3.int:占用32位-2^32~2^31-1
4.long : 占用64位-2^63~2^64-1
整数常量默认就是int类型
注1:如果直接将一个较小整数常量(在byte或者short范围内)赋值给byte或者short,系统自动将其作为byte或者short类型处理
byte a = 30;
注2:如果使用一个巨大的整数常量(超过int表示范围),系统不会自动将其当成long类型处理,需要在数值后加l或者L作为后缀
long a = 123456789987000l;
可以直接把一个较小的正数常量赋值给long类型变量,不加l或L作为后缀,不是因为java会把这个较小常量当成long类型来处理,java依旧把这个常量当做int类型处理,只是这个int类型的值会自动类型转换到long类型。[隐式]
long a = 30;
3.2浮点型:float,double
note:1.float:32位,后缀f或者F
double:64位,后缀为d或者D
2.默认类型为double
基本数据类型转换:
1.隐式数据类型转换
小范围----大范围
2.显示数据类型转换(强制数据类型转换,语法
(targetType)value)
大范围----》小范围
运算:
1.所有byte,short,char类型参与运算自动提升至int类型
2.整个算数表达式的数据类型自动提升到与表达式中最高等级操作数相同的类型
short a = 10;
short b = a-2;
byte a = 10;
short b = 200;
char c = 'a';
int d = 20;
double e = 0.1;
double res = a+b+c+d+e;
引用类型:在java中每定义一个类都相当于声明了一种类型。这种类型称之为类类型/引用类型。
String :java中的一个用来代表字符串的类(java.lang.String)。一个有字符组成的序列称之为字符串
String s = "abc";//直接量
String s1 = new String("abc");
运算:
如果表达式中包含了字符串,加号将是字符串连接运算符,而不是加法运算
"hello"+'a'+1;
'a'+1+"hello";
1+2+"hello";
java为8中基本类型都提供了对应的包装类
Boolean,Byte,Short,Integer,Long,Character,Float,Double,8个包装类都提供了
parseXxx(String str)的方法用于将字符串转换为基本类型。
define:[访问修饰符] class className{
}
Object:具体,抽象为Class
Class《----- Object:抽取对象具有的公有的属性(成员变量)和行为(方法) 类的实例
object <----- Class
类:对象的模板
对象:类的实例
1.抽象为类:
public class Student{
//成员变量
public String name;
public String gender;
public int age;
public long snum;
public String jiao;//角
//成员方法
public void study(){
System.out.println("正在学习");
}
pubic void sleep(){
}
public void play(){
}
/*public void flay(){
}*/
........
}
2.实例化对象
Student stu1 = new Student();//构造器
3.操作对象的属性和行为
stu1.name
stu1.name = "tom";
stu1.study();
变量:值有可能会发生变化的标识。
语法:DataType varName [= value];
note:java中的变量一定要先初始化才能使用。
数据类型:
byte short int long char float double boolean
1.基本数据类型的变量:
1.总共八种
2.赋值 var = 基本数据类型所能表示范围的值
2.引用类型的变量:
1.ClassType var;
2.引用类型的变量赋值=new ClassType([params]);
Student s = new Student();
Student s;
Student s = null;
Student s = new Student();
//8月15--打月饼
//模具--黑糖,果仁,葡萄干... 面
//模具--挖出来成了一个个的月饼
Student s = new Student("zhangsan");//构造器
3.特殊的引用类型:String
String s = "abc";//直接量
1.局部变量:
1).声明在方法体部
2).使用之前必须被显示进行初始化
3).作用范围从声明开始到所在代码块结束(在他定义之前离他最近的{}所扩起来的范围)
4).在局部变量作用范围之内不能存在同名的变量。
2.成员变量:声明在类体部,方法体外
1.实例变量
1.依赖于实例对象(类对象)的存在才会存在
2.不需要进行显示的初始化,会自动使用默认的初始值进行初始化
byte short int long float double char boolean 引用
0 0 0 0l 0.0f 0.0d '' false null
3.作用范围,类体部的所有实例方法(所有非static修饰的方法)+匿名代码块(直接出现在类体部的{})
4.在方法中可以定义和实例变量同名的变量,访问的时候采用就近原则。
2.类变量(static 静态)
static DataType varName:属于该类[类变量]
DataType varName:属于某个对象[实例变量]
一、操作符
1.算术运算符
+ - * / % ++(自增) --(自减)
++a a++ ===> a=a+1
++a:先执行a=a+1,再用a的值参与运算
a++:先使用a的值参与运算,再执行a=a+1;
--a a-- ===> a=a-1
--a:先执行a=a-1,再用a的值参与运算
a--:先使用a的值参与运算,再执行a=a-1;
+:字符串拼接
2.比较运算符
> < >= <= == != instanceof
A instanceof B:A这个对象是否属于B这种类型。
3.逻辑运算符:使用逻辑运算符进行操作的必须是两个boolean类型的值。
&& ||
&& : 操作数同时为true,结果才为true
|| : 操作数同时为false,结果才为false
&& || : 短路原则
&&:如果第一个表达式的操作结果为假,后续表达式不在参与运算,直接返回为假
||:如果第一个表达式结果为真,后续不在运算,直接返回true
6.条件运算符/三目运算符
boolean_expression?trueV:falseV
7.赋值运算符和复合赋值运算符
= += -= *= /=....
复合赋值运算符:自动进行数据类型转换
1.顺序流程,按照程序的声明顺序执行。
2.条件语句:
if ... else if ...else
1).if(){
}
2).if(){
}else if(){
}else if.....
3).if(){
}else{
}
4).if(){
}else if(){
}...else if(){
}else{
}
3.循环语句
for(int i=0;i<10;i++){
Sys...
}
1.for(expr1;boolean_expression;exp3){
block A;
}
note:
1.expr1,boolean_expression,exp3可以都不存在,但是;必须存在。
2. expr1:循环初始条件
boolean_exp:当结果为true,执行循环体(block A),循环执行的条件。
exp3:循环状态的改变。
3.执行过程:
for(循环初始条件;循环执行的条件;循环状态的改变){
循环体
}
循环初始条件--循环执行的条件--循环体--循环状态的改变--循环执行的条件--循环体--循环状态的改变..
2.while:当型循环或者前测试循环。
1.循环初始状态设置。
while(boolean_Expression(循环执行的条件)){
block A{
3.循环状态的改变。
}
}
note:如果初始状态就不满足循环执行的条件,那么循环体就没有执行的机会。
3.do...while循环:后测试循环。无论初始条件是否满足循环执行的条件,都保证循环体有一次执行的机会。
1.初始状态。
do{
2.循环状态的改变
}while(boolean_expression);
4.循环的嵌套
打印四层的金字塔
* 1 3 1
*** 2 2 3
***** 3 1 5
******* 4 0 7
n 4-n 2n-1
for(int i=1;i<=4;i++){
System.out.print();
}
5.break,continue
break:终止break所在循环体
continue:跳出本次循环进入下一次循环。
break label:跳出(终止)label所指定的循环体
continue label:跳出本次循环,进入labe所指定循环的下一次循环。
return:exit method
一、数组的基本概念:
数组:一组具有相同数据类型数据的集合。数组也是一种类型
datatype[] varName;
int[] nums;
short[] shos;
String[] strs;
Student[] stus;
Student s;
s = new Student();
note:
1.创建出的数组就是一个对象。
2.对象具有属性。数组也有属性:
1.length:数组的长度。
2.member:数据中的每一个数据都是数组的属性。
3.声明一个数组,数组中所能存放的数据类型就固定了。
4.数组要求在内存中需要分配 连续的内存空间进行存储。所以数组在创建的时候需要指明数组的大小(length).并且数组一旦创建,数组的长度不能改变。
5.new,数组中的每一个数据成员也都会使用相应数据类型的默认初始值进行初始化。
6.声明一个数组变量,不代表创建了一个数组对象。
二、数组的声明,创建,初始化
声明:
DataType[] var;
DataType var[];
int[] arr1;
int arr2[];
创建:
var = new DataType[length];
arr1 = new int[10];
arr1[0] = 10;
arr1[2] = 11;
arr1[arr1.length-1] = 100;
初始化:
var[index(0---length-1)]
a[0] = 1;
a[1] = 2;
或者:
int[] a = {1,2,3,4};
int[] a = new int[]{1,2,3,4};
int[] b ;
b = new int[]{1,2,3,4};
以这种方式创建同时初始化数组,那么数组[]中一定不能有长度的定义.
三、数组的操作:
数组变量名[index(0--length-1)]
1.遍历:
for(int i= 0;i
一 对象:
概念:万物皆对象
Person{
String name;//共有属性--抽象--成员变量
int age;
.......
public void run(){//行为--抽象--方法
}
public void jump(){
}
}
创建对象: Person p1 = new Person();
p1.name = "tom";
p1.age = 12;
p1.run();
E-R:图
类型:顾客,商品,订单,收货地址
顾客[name,age,phone..]
public class customer{
String name;
}
public class item{
//
//
}
public class order{
public Date date;
public double prce;
}
note: 1.具体的
2.对象是唯一的.
3.对象是类的实例
二 类:
类型
note:1.抽象的概念,抽象的对象所具有的共有属性(成员变量)和行为(方法)
2.元数据(描述数据的数据)
3.类是对象的模板.
4.java编程过程中,就是抽象一个一个的类的过程.
java是面对对象的程序设计语言,java提供了定义类,属性,方法等最基本的功能,类可以被认为是一种自定义的数据类型,可以使用类来定义变量,称为引用变量,引用变量将引用到类的对象。
类用于描述客观世界里某一类对象的共有特征,而对象则是类的具体存在,java程序使用类的构造器来创建该类的对象
三 类定义:
public class test1{// //}:test1能在本类中,不同包中
new test1()
public:共有的访问权限
static: 修饰属性或者方法,声明:属性或者方法是属于类本身,还是属于类的 实例[对象]
class Person{
//成员变量
public String name;//实例变量
public static int footNum;//类变量[静态变量]
public Person(){//构造器
//可执行代码
}
//成员方法
public void run(){//实例方法
//可执行代码
}
public static void print(){//类方法[静态方法]
//可执行代码
}
}
[修饰符[public final abstract ]] class className [extends superClass] [implements interface1,interface,....]{
1.成员变量的定义:
1.实例变量:
2.类变量(static)
2.成员方法:
1.实例方法
2.类方法(static)
3.构造器:
[修饰符] 类名([参数列表]){}
}
四 成员变量:
Person{ name/age...
String name;
public String name;
public String name="tom";
public static String name = "tom";
protected String name="tom";
private String name="tom";
}
[修饰符] DataType varName [= 默认值];
修饰符:修饰符可以省略,也可以是public,protected,private,static,final,其中public,protected,private三个最多选一个,可以与static、final组合起来修饰成员变量
DataTtpe:属性类型,可以使java语言允许的任何数据类型,包括基本数据类型和引用类型
varName:属性名,合法标识符,表意性强
默认值:定义Filed还可以指定一个可选的默认值
1.实例变量:依赖于对象的存在才存在(才有意义)的变量
访问: 创建对象->对象名.变量名
同一个类中:对象名
2.类变量(static修饰):类存在即存在,被类的所有实例所共享.
访问:
1.类名.变量名
2.对象名.变量名
3.当前类中---变量名
五 成员方法:方法是类或对象的行为特征的抽象,方法不能独立存在,要么属于类,要么属于对象[static]
//doBall
[修饰符] returnType methodName(DataType param1,DataType param2,.....){
block;
}
void doTest1(){}
public void doTest1(){}
public static void doTest1(){}
public static void doTest1(int p1,String p2){}
//调用方法时:doTest1(传参:和方法定义时的参数列表保持一致)
修饰符:修饰符可以省略,也可以是public,protected,private,static,final,abstract,其中public,protected,private三个最多只能选一个,abstract和final最多只能出现一个,它们可以与static组合起来修饰。
returnType:方法返回类型,可以是java语言允许的任何数据类型,包括基本类型和引用类型,如果声明了方法返回值类型,则方法体内必须有一个【有效的】return语句,该语句返回一个变量或一个表达式,这个变量或表达式的结果 类型必须与此处声明的类型匹配。
如果方法没有返回值,则必须使用void来声明没有返回值。
方法名:与成员变量基本相同
形参列表:用于定义该方法可以接受的参数,由零到多组【参数类型 形式参数名】组合而成,多组之间逗号(,)隔开,
一旦在定义方法时制定了形参列表,则调用该方法时必须传入【对应】的参数值。
方法体内多条可执行语句之间的执行顺序,排在方法体前面的语句总是先执行,排在方法体后面的语句总是后执行。
static是一个特殊的关键字,可用于修饰方法,成员变量(属性)等成员,static修饰的成员表名它属于这个类本身,而不是属于创建出来的该类的单个实例。所以通常把static修饰的Field和方法称为:类变量,类方法,不使用static修饰的属于该类的单个实例,称为:实例变量,实例方法。
【静态成员不能直接访问非静态成员】
note:returnType:声明方法的返回值的类型.如果方法没有返回值,就必须使用void进行标识.假设方法的返回类型不是void,那么方法体中的每一个分支语句都必须有return value;
一个方法只能有一个返回类型.
计算两个数的最大值
1.实例方法:
调用:构建对象---->对象名.方法名([param,..])
同一个类中:方法名([param...]);
2.类方法(static):
Math.random()
Arrays.toString(type[]);
System.arrayCopy(src[],index,dest[],index,length);
调用:
1.类名.方法名([param...])
2.对象名.方法名([param...]);
3.同一个类中 方法名([param..])
方法详解:类或对象行为特征的抽象,方法时对象重要的组成部分,不能独立存在,必须定义在类中,在逻辑上方法要么属于类,要么属于对象。因此,方法也不能独立执行,执行方法时必须使用类或者对象来作为调用者,即所有方法都必须使用“类.方法”或者"对象.方法"的形式来调用,同类中可以使用this或者当前类调用
六 参数的传递:
1.形参:定义在方法声明的小括号中.用来接受方法调用过程中传递过来的数据,称为形参
2.实参:调用方法时实际传给形参的,实际参与运算的参数值数据。
java的实参值传递方式只有一种:值传递,就是将实际参数值的复制品传入方法中,而参数本身不会受到任何影响。
基本类型:复制值;引用类型:复制引用,也就是对象的地址值。
递归
七 方法的重载:
1.在同一个类中
2.方法名字相同,参数列表不同
1.参数个数不同
2.参数类型不同
3.参数位置不同(参数类型不同)
3.和返回类型无关.
public int add()
public int add()
public int add()
note:
1.如果方法调用过程中,可变参数的方法和固定参数个数的方法能够同时匹配,优先执行固定参数.(先精确后模糊)
2.如果有两个可变参的方法能够同时匹配上,那么运行出错
3.一个方法要求只能有一个可变长度的参数.并且可变长参数应该位于参数列表的最后一项.
八.构造器
专门用来构建对象的一个存在。创建对象的根本途径是调用构造器,通过new关键字来调用某个类的构造器即可创建这个类的实例.
定义语法:
[修饰符] void className(DataType param1,DataType param2.....){
对象的初始化操作等可执行语句
}
修饰符:可以省略,也可以是public、protected、private其中之一
note:
1.构造器的名字和类名是保持一致
2.构造一定没有返回类型.(如果加了返回类型,那么他就不在是构造器,而变成普通的方法.)
3.构建对象的时候调用.new Constructor(param...);
4.如果在类中没有显示的定义构造器,那么java会自动提供一个默认的无参的且方法体空白的构造器.
如果类中显示的定义了构造器,那么默认构造器将不再提供.(一般情况下,如果类中显示的定义了自己的构造器,我们会随手加上一个无参的构造器.)
5.构造器用来构建对象,一般构造器中不做复杂的操作,主要用来进行对象的初始化(初始化成员变量.)
6.构造器可以被重载
7.构造器之间可以相互调用来简化构造器的过程,调用方式:
this(param...),对于构造器的调用一定要位于操作的第一行.
对象的产生和使用:
创建对象的根本途径是调用构造器,通过new关键字来调用某个类的构造器即可创建这个类的实例.
如果访问权限允许,类中定义的方法和属性都可以通过类或者实例来调用。类名.属性/方法 实例.属性/方法
对象引用
Stduent s = new Student()//堆区开辟一片空间
这行代码创建了两个东西:一个是s变量一个是Student对象。对象保存在堆区,s变量保存在栈区。java让引用变量指向对象,也就是说,s这个引用变量中存放的仅仅是一个引用[地址],它指向实际的对象,与数组一样。
堆内存中可以有多个对象,一个对象可以有多个引用,即多个引用变量指向同一个对象,如:
Student s2 = s;
这样s和s2保存相同的地址值,指向堆中的同一个person对象,不论访问s还是s2的实现方法,都是访问的同一个Person对象,返回同样的结果。如果堆内存中的对象没有任何变量指向,name程序无法再访问该对象,这个对象将被java垃圾回收机制回收该对象,释放该对象所占的内存区,比如:
s = null;
s2 = new Student();
九 this关键字:
当前对象的引用.一个类调用本类的实例其他方法,直接使用this,不需要再创建一个对象再调用第二个对象的方法。
作用:
1.调用当前对象的实例变量,实例方法
2.有同名局部变量时区分实例变量与局部变量
3.调用构造器,如果使用this调用构造器,这句话一定位于构造器的第一行.
4.作为方法返回值,返回本身对象
同一个对象两个成员之间有依赖,java允许对象的一个成员在合理情况下直接调用另一个成员,可以省略this前缀。
对于static修饰的成员,属于类本身,不属于实例,所以使用this关键字将无法指向合适的对象,所以static修饰方法中不能使用tis引用,所以static修饰的方法或变量不能访问非static的普通成员,因此【静态成员不能直接访问非静态成员】,除非在静态方法中新建对象或者在静态变量中赋值时执行静态方法。
十 对象的构建和初始化过程.
开发者定义java类之后,就可以使用new关键字来创建指定类的对象了,每个类可以创建任意多个对象,多个对象的field值可以不同
Person p = new Person(1L,"zhangsan","女");
1.申请内存空间存储对象,并且使用默认的初始值进行实例变量的初始化(0/null/false).
2.查看成员 变量定义时是否有初始值.如果有使用定义时的初始值进行修改[或初始化代码块,顺序执行].
3.调用构造器执行.
package com.briup.corejava //http://briup.com
public[访问修饰符default/package] class ClassName{
//[static类/实例]成员变量,初始化
//1.成员变量有默认值0/false/null
//2.定义成员变量时赋初值
// 初始化代码块
//3.构造器
[static]
{
age = 30;
}
public[protected,d,private] static int age = 10;
public[..] double heigh = 177;
public Student student = new Student();
public Student[] students = new Student[100];
//[static类/实例]成员方法
public[protected,d,private] [static] int/void methodName(param...){
if(){
}else{
}
return 50;
}
//构造器:默认提供无参构造器,显示定义[随手加上无参]
//构造器可以重载: new 构造器(参数列表)
public ClassName(int heigh){
//System.out.println("");int a= 10; a++;
this.heigh = heigh;
age = 20;
student = null;
students[0] = new Student("zs");
int b = this.methodName(age);
//int c = noReture();
System.out.print(this.methodName(age));
}
//[static静态/普通]初始化代码块
}
面向对象编程的特征:封装,继承,多态
十一 .封装
封装.封装的过程其实就是定义一个类的过程.面向对象编程的第一个特征.
目的:实现信息的隐藏包括行为实现细节的隐藏。将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。类似于现实生活中一个人的age,不能随意更改。
方式:1.通过控制信息的访问权限.(访问修饰符private public),不允许外部直接访问
2.把方法暴露出来,让方法来控制对这些属性进行安全的访问和操作
通过访问修饰符:把该隐藏的隐藏起来,该暴露的暴露出来。
三种:public;protected;private;以及什么都不写default
public(公共访问权限):类本身,外部类都能访问,不论是否在同包下,是否有继承关系
protected(子类访问权限):类本身,外部类在同包下或者有继承关系可以访问
default(默认,包访问权限):类本身,或者在同包下的外部类可以访问
private(当前类访问权限):类本身,只有在当前类中才能被访问
同一个类 同一个包 所在类的子类 全局外部
public 1 1 1 1
protected 1 1 1
package 1 1
private 1
private:私有的,个人的(只能自己访问.)
public class Person{
private long pid;
private String name;
//设置值,取值方法
public void setPid(long pid){
this.pid = pid;
}
public long getPid(){
return pid;
}
}
如果实现了信息的封装,那么要提供给所有人一个共有的访问入口
private Type Filed
public Type getFiled()
public void setFiled(Type param)
javaBean
getter setter
get+"upper(F)"iled:方法名
set+成员变量首字母大写:方法名
getter/setter
// name getName setName
约定
package import
十二 继承
1. 满足 is a 语义关系[instanceof]
具有继承关系的两个类 A extends B,A称为子类,B称为父类,继承就可以让A从B中继承下来B中已经存在的,非私有的一些属性和行为.在java中实现继承的目的其实就是为了实现代码的复用,简化子类的构建过程.
修饰符 class className extend superClass{
}
动物(Animal) ---- 猫
动物(Animal) ---- 狗
单继承
ClassA extends ClassB
ClassB extends ClassC
Animal
dog extends Animal
Object:所有类的父类
共有的public 方法:toString(),equals()....
同时父类也可以实现继承 生物--动物。如果定义一个类时没有显示声明父类,则这个类默认继承自java.lang.Object,因此所有类都直接或者间接地继承自【Object类】
note:
1.如果存在子父类继承关系,那么子类构造器一定会显示或者隐式的调用父类的构造器.(如果没有显示的调用父类的构造器,那么会默认调用父类的无参构造器,如果需要显示调用父类构造器super(...),对于父类构造器的调用一定位于子类构造器的第一行.)
2.this,super调用构造器的操作不同时出现.
3.java中的继承属于单继承.
4.构造器不能被继承,属性和行为可以.
5.子类除了能够继承父类的属性和行为之外还可以具有自己的特征和行为.
创建类:
先加载类class[加载静态变量、静态代码块],
普通代码块[初始化实例变量]--执行构造器
创建子类:执行子类构造器之前--执行父类构造器
加载子类之前先加载父类
加载子类之前先加载父类
加载子类之前先加载父类
十三 super关键字
可以调用父类被覆盖的实例方法或者构造器
1.调用父类的构造器super(...),必须位于第一行.
2.父类的属性和行为.super.method(..),super.varName.
同时:由于调用子类构造器初始化子类对象时,父类构造器总会在子类构造器之前执行,而且执行父类构造器时,系统会再上溯父类的父类的构造器,所以,创建任何java对象,最先执行的总是Object的构造器。
十四 Cast:
引用类型的数据类型转换:
1.隐士数据类型转换
小范围----大范围
子类 ---- 父类
直接使用父类类型的引用直接接受子类对象.
2.显示数据类型转换
大范围---小范围
将父类类型的引用变量转换为子类类型的引用时需要强制类型转换.(类型转换之前一定先确保使用Instanceof来判断的话,转换的父类类型的引用类型所指向的实际对象是否属于要转换成的子类类型.)
a instanceof Class
十五 方法的重写(覆盖)
在子类中声明和父类完全相同的行为,称之为方法的重写(覆盖).
1.发生在子父类.子类具有和父类同名的方法
2.子类方法的声明和父类方法的声明完全保持一致(返回类型,方法名字,参数列表要求完全一致)
3.访问权限不能被缩小.
4.异常不能被扩大.
注:重写的方法:实例重写实例,类方法重写类方法,不能一个是实例,一个是类。
//请描述方法重载与重写
重载:发生在同一个类中,不同方法间:
方法名相同,参数列表不同,返回类型无关
[参数个数,类型,位置]
重写:发生在父子类继承中,子类重写从父类继承的方法,要求:
方法名相同,参数列表相同,返回类型相同[小]
访问权限不能被缩小,异常不能被扩大
十六 多态
多种表现形态.
java引用变量有两个类型:编译时类型和运行时类型,编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定,如果编译时类型和运行时类型不一致,就可能出现多态。
编译时多态:方法的重载
(动物,水果,人)
(狗,猫 苹果西瓜 学生老师)
Animal a1
Animal a2 = new Dog(); dog==run
a1.run();
a2.run();
运行时多态:相同类域的不同对象在调用相同方法时的表现不同.(方法重写.)
多态的体现:
1.有子父类继承关系存在,子类覆盖父类的行为,或者有接口和实现类的关系存在,并且实现类实现了接口中所有的抽象方法.
2.父类类型的引用指向子类的对象.有接口类类型的引用指向实现类的对象.
3.调用被子类重写了的方法,调用实现类中实现的接口中定义的方法.
note:1.属性是没有多态行为的,使用父类类型的引用,只看看到父类类型的属性,使用子类类型的应用可以看到从父类继承的属性和自定义的属性
2.static修饰的方法不能被覆盖为非static修饰的方法.并且就算static的方法被子类覆盖也不会有多态的体现.
编写java程序时,引用类型只能调用它编译时类型的方法,而不能调用它运行时类型的方法,及时它实际所引用的对象却是包含该方法,如果需要应用到运行时实际类型的方法,可以进行类型强制转换。 SonType son = (SonType)fatherObject;
需要注意,如父类对象fatherObject转换为子类,必须fatherObject这个对象实际上就是子类实例才行,否则引发ClassCastException。
组合:如果需要复用一个类,除了把这个类当成基类来继承之外,还可以把该类当做另一个类的组成成分。如作为引用类型的成员变量。
十七:包装类:解决8种基本数据类型的变量不能被当做Object类型变量使用的问题
boolean byte short int long char float double
Boolean,Byte,Short,Integer,Long,Character,Float,Double
把基本类型变量转换为对应包装类对象,以及把字符串包装为包装类对象
boolean b = false;
Boolean b1 = new Boolean(b1);
其他类似
或者把字符串转换为包装类型
Float f1 = new Float("1.23");
把包装类转换为基本类型变量
boolean b3 = b2.booleanValue();
int b4 = IntObj.intvalue();
基本转换包装:new WrapperClass(primitive)
包装转换基本: WrapperInstance.xxxValue();
JDK1.5提供自动装箱[基本类型变量直接赋值给包装类对象]和拆箱[包装类对象直接赋值给基本类型变量]
Integer i1 = 5;
int i2 = i1;
包装类还提供了与字符串之间转换的方式
字符串转换基本类型变量:WrapperClass.parseXxx(String s)
基本类型变量转换为String:String.valueOf(primitive);
封装,继承[子类构建对象会显示或者隐式调用父类构造器],多态
Object:重写toString() 重写equals(){ == }:值相等
final:不可变 【类】【方法】【变量】:只能赋值一次
abstract:抽象 【类】【方法();】
不能实例化,目的:被继承[子类:要么重写[创建子类对象],要么也成为抽象类]
有构造器
Object 处理对象:java对象都是Object类的实例,都可以直接调用该类中定义的方法,这些方法提供了处理java对象的通用方法
打印对象和toString()方法:直接打印如Person对象,得到的结果实际是Person的toString方法的返回值:类型@6为十六进制数字
toString方法是Object中的一个实例方法,所有其子类对象都有toString方法
而且所有java对象都可以与字符串进行连接运算,当java对象和字符串进行连接运算时,系统自动调用java对象的toString方法的返回值和字符串进行连接运算
p+"hello"<==>p.toString()+"hello"
toString是一个“自我描述”的方法,通常我们希望打印对象时,能得到该对象的“自我描述”信息,告诉外界该对象具有的状态信息,但是默认返回的是“类名+@+hashCode”的值,所以为了实现“自我描述”功能,就必须重写Object的toString方法。
==和equals
测试两个变量是否相等,使用==运算符或者equals方法
==:基本类型变量,只要变量的值相等,就返回true,引用类型变量,指向同一个对象时才返回true,不可比较没有父子关系的两个对象
注意String,字符串直接量保存在常量池,new String("hello")将创建出两个对象
equals:很多时候,希望判断两个引用类型是否相等,希望有一种类似于“值相等”的判断规则,使用equals方法
但是默认判断标准和==没有区别,所以我们可以重写equals方法,如String已经重写了equals方法了
StringBuilder sbr = new StringBuilder();
sbr.append(str2).append(str3);
sbr.toString();
StringBuffer:线程安全
final:可以修饰类、变量和方法,代表不可改变
修饰变量:表示变量一旦获得了初始值就不可被改变,可以修改类变量,实例变量,局部变量形参
final成员变量:java语法规定:final修饰的成员变量必须由程序员显示地指定初始值,系统不会对final成员进行隐式初始化
类变量:必须在静态初始化代码块中或者声明变量时就指定初始值
实例变量:必须在普通代码块,声明变量时或者构造器中指定初始值
final局部变量:系统本就不会对局部变量初始化,所有final修饰的局部变量在定义时可以指定默认值,也可以不指定
如果定义时没有指定默认值,则在后面的代码中只能赋值一次,如果是形参则由调用方法时传进来的实参值初始化
final基本类型变量和引用类型变量
基本类型:值不可改变
引用类型:引用地址不改变,一直指向同一个对象就可以,对象的属性可以改变
final修饰的变量只要在定义时就指定初值,或者使用基本表达式赋值,没有访问普通变量或者调用方法,就是常量
修饰方法:
final修饰的方法不能被重写,如Object中的getClass()
修饰类:
final修饰的类不可以有子类,例如
abstract :
1.修饰类:
1.抽象类
类 是对 对象的抽象.
抽象类 是对 类的抽象.
2.抽象类不能被实例化,即使没有抽象方法,但是可以声明抽象类类型的变量
Animal an = new Cat();
抽象类使用abstract修饰
3.抽象类存在的目的是为了被子类继承的.如果一个类继承了一个抽象类,那么必须实现抽象类中所有的抽象方法.或者自己本身也是一个抽象类.
4.抽象类中可以有普通属性,和行为,抽象类中的方法不一定都是抽象方法.
final[类不能继承,方法不能重写]和abstract不能同时使用
static不修饰抽象方法
2.修饰方法
1.抽象方法
2.抽象方法不能有方法体
public abstract void test();
3.抽象方法所在的类必须是抽象类.
4.抽象方法存在的目的就是用来被重写或者被实现的.
抽象类作为中间产品,实现可实现的,把不实现的交给子类实现
public static final String name = "张三";
String name = "张三";
static final 不能 abstracted
public abstracted int method1();
int method1();
public interface inName{
void eat();
int run();
String goPlay();
}
1.接口就是用来定义规则的.public或者默认
2.接口中所有的方法默认都是public abstract的
3.接口是用来被实现的.一个类实现了这个接口,就必须实现这个接口中所定义的所有的方法.
4.接口中所定义的所有的成员变量默认都是public static final,关键字可以省略
5.接口也不能被实例化,但是可以声明接口类型的变量,接口类型的变量可以接受实现类的对象.
Driver d = new KeyBord();
Driver mouse = new Mouse();
6.接口可以多继承.
interface A{}
interface B{}
interface C extends A,B{}
7.类只能继承一个父类,但是可以实现多个接口
interface A{}
interface B{}
class C implments A,B{}
8.某种意义上接口的存在规避了java不能多继承所带来的操作弊端.
9.接口是比抽象类还抽象的存在,接口是抽象类的极致抽象.
door都有open和close的功能,如果要添加alarm功能呢
[模板,中间件,可以实现的提供了功能,但是还有一些留给子类重写]
public abstract class door{
public abstract void open();
close();
}
[功能,行为,方法,制定规则]
plublc interface alarm{
alarm();
}
只要是门,都得实现alarm功能
GreenDoor extends door implemnets alarm
redDoor extends door implemnets alarm
blackDoor extends alarm
//报警器
fireAlarm implemnets alarm{
}
一个数据:基本类型数据
一些数据:对象--引用类型
一组数据:数组:长度不可变,保存的数据类型不可变
一组数据:长度可以改变,类型也不固定,集合
一、集合概述:为了保存长度可变化的,不同数据类型、具有映射关系的数据,【对象】
java集合主要分为Set、List、Map三种体系,其中
List代表:有序、可重复的集合
Set代表:无序、不可重复的集合
Map代表:具有映射、关联关系的集合,key--value:键值对
java集合的三种体系由两个接口派生而出:Collection和Map
Collection接口:制定规则,抽象方法;
Collection接口是List(extends)和Set接口的父接口,也就是说List与Set下边才是实现类。
Collection接口作为父接口,它里面定义的方法既可用于操作List集合,也可用于操作Set集合,[接口的实现类需要实现所有抽象方法。所以实现类肯定都需要重写方法的]
boolean add(Object o)
boolean remove(Object o)
int size()
Iterator iterator();
Object[] toArray()
boolean addAll(Collection c)
boolean removeAll(Collection c)
clear()
boolean contains(Object o)
boolean containsAll(Collection c)
boolean retainAll(Coolection c)删除所有c中不包含的
boolean isEmpty()
Iterator接口:主要用于遍历Collection集合中的元素,其对象被称为迭代器,与Collection派系关联(List,Set)
boolean hashNext()
Object Next()
remove() 删除上一次next方法返回的元素
二:体系1:List
List:有序、可重复,所以多个null也以,作为Collection的子接口,上边的方法也都是可以使用,由于List有序index,所以增加了按照索引操作集合元素的方法。
泛型:E:任一类型 ,String Integer, Student,P
x*2+3 = 9
x*2 = 6
x = 3
x*3+3 = 9
x = 2
x:代表一个数
变量:代表某个值
类型变量:代表某个类型
void add(int index,Object obj);
Object remove(int index);
Object set(int index,Object obj);//替换
Object get(int index);
boolean addAll(int index,Collection c)
int indexOf(Object o);第一次出现的索引
int lastIndex(Object obj);最后一次的索引
List subList(int fromIndex,int toIndex);子集合
上边↑,所有List集合可调用的方法,与Set相比,增加了可用索引增删改查数据的方法。List集合判断两个元素是否相等的标准是只要两个元素的equals(0方法返回true即可。
list的remove(object obj)是调用obj的equals()方法一次与集合元素进行比较,比较结果为true,则删除
常用实现类:ArrayList:索引
体系2:Set
Set:无序,不重复(根据equals比较的),作为Collection的子接口,Collection上边的方法自然也都是可以使用,由于Set无序,所以它也有自己的特色。判断是否相等是使用equals()方法[hashCode]或者CompareTo()
Hashset:是Set接口的实现,常用,按照hash算法存储数据,按照hashCode值存储定位。由于Set不可重复,所以它的判断标准是当向HashSet集合中存放新对象的时候,调用该对象的hashCode()方法,以这个值判断对象的存储位置,所以如果hashcode()方法返回值不同,就不需用使用equals比较,直接判断不重复[可添加],即使equals方法判断相等,存储在不同的位置。所以在应对HashSet的“不可重复”特性的时候,需要重写hashcode()方法和equals()方法。重写hashcode()方法的目的是使当两个对象的equals()方法返回true时,保证hashcode()方法返回的值也相等。(这样才有equals比较机会)同时equals方法为false时,hashcode的值要尽可能的不同,否则同一位置保存多个值,降低效率
SortedSet:接口,Set的子接口
TreeSet:SortedSet的实现类,实现了“排序”,不可重复(仅以排序确定,为0,认为相等,不予添加,否则可添加,所以需重写comparaTo与equals,保证equals相等时,返回0),不可为null
TreeSet作为特色实现类,有自己特有的方法:
first();last();comparator();...
自然排序:存放在TreeSet中的对象的类必须实现comparable接口,实现其comparTo(obj o)方法
客户化排序:初始化TreeSet的时候参数需要一个comparator接口的实现类,实现其compare(Obj o1,Obj o2)方法
Map系列:
key1-value1
key2-value2
key3-value3
key4-value4
key(equals)不允许重复,value可以重复(equals)
Object put(Object key,Object value),已有k-v,覆盖
Object remove(Object key)
Object get(Object key)
int size()
Set keySet()
Collection values()
Set entrySet()-----Entry:getKey(),getValue(),setValue()
boolean containsKey(Object key)
boolean containsValue(Object value)
HashMap:只能有一个null的key(判断key是否重复:hashCode,equals,与hashSet标准一致。判断value:equals)
sortMap接口:Map的子接口
TreeMap:sortMap的实现类
自然排序,客户化排序
key不能重复的标准:与TreeSet一样,comparaTo方法是否为0,所以最好让equals相等时,comparaTo也相等
[keySet() entrySet()]
匿名内部类
1.没有名字的局部内部类.
2.不会使用关键字class,implements,extends
3.没有构造器.
4.只能够访问final修饰的局部变量
5.所有的匿名内部类都隐式的继承自一个父类或者实现了一个接口.
Exceptions
尽管人人都希望所处理的事情能顺利进行,所操纵的机器能正常运转,但在现实生活中总会遇到各种异常情况。例如职工小
王开车去上班,在正常情况下, 小王会准时到达单位。但是天有不测风云,在小王去上班时,可能会遇到一些异常情况:比
如小王的车子出了故障,小王只能改为步行,结果上班迟到;或者遭遇车祸而受伤,请假。
异常情况会改变正常的流程,导致恶劣的后果。为了减少损失,应该事先充分预计到所有可能出现的异常,然后采取解决措施。
程序运行时也会遇到各种异常情况,异常处理的原则和现实生活中异常处理原则相似。首先应该预计到所有可能出现的异常,
然后考虑能否完全避免异常,如果不能完全避免,再考虑异常发生时的具体处理方法。
Java语言提供了一套完善的异常处理机制。正确运用这套机制,有助于提高程序的健壮性。所谓程序的健壮性,指程序在多数
情况下能够正常运行,返回预期的正确结果;如果偶尔遇到异常情况,程序也可采取周到的解决措施。
Java语言按照面向对象的思想来处理异常,使得程序具有更好的可维护性。Java异常处理机制具有以下优点:
. 把各种不同类型的异常情况进行分类,用Java类来表示异常情况,这种类被称为异常类。把异常情况表示成异常类,可以充
分发挥类的可扩展和可重用的优势。
. 异常流程的代码和正常流程的代码分离,提高了程序的可读性,简化了程序的结构。
. 可以灵活地处理异常,如果当前方法有能力处理异常,就捕获并处理它,否则只需要抛出异常,由方法调用者来处理它。
知识点:一. 异常的基本概念
1. 异常产生的条件
或者称为异常情况。在Java代码中哪些是异常情况呢? 例如:
a. 整数相除运算中,分母为0;
b. 通过一个没有指向任何具体对象的引用去访问对象的方法;
c. 使用数组长度作为下标访问数组元素;
d. 将一个引用强制转化成不相干的对象;
等等;
2. 异常会改变正常程序流程;
异常产生后,正常的程序流程被打破了,要么程序中止,要么程序被转向异常处理的语句;
3. 当一个异常的事件发生后,该异常被虚拟机封装形成异常对象抛出。
4. 用来负责处理异常的代码被称为异常处理器
5. 通过异常处理器来捕获异常
二.try...catch语句
在Java语言中,用try...catch语句来捕获处理异常。格式如下:
try {
可能会出现异常情况的代码;
} catch(异常类型 异常参数) {
异常处理代码
} catch(异常类型 异常参数) {
异常处理代码
}
1. 如果try代码块中没有抛出异常,try代码块中语句会顺序执行完,catch代码块内容不会被执行;
2. 如果try代码块中抛出catch代码块所声明的异常类型对象,程序跳过try代码块中接下来代码,直接执行
catch代码块中对应内容;
a. 可以存在多个catch代码块,究竟执行哪个,看抛出的异常对象是否是catch代码块中异常类型;
b. 异常只能被一个异常处理器所处理, 不能声明两个异常处理器处理相同类型的异常;
c. 多个catch语句块所声明的异常类型不能越来越小;
d. 不能捕获一个在try语句块中没有抛出的异常;
3. 如果try代码块中抛出catch代码块未声明的异常类型对象,异常被抛给调用者;哪个调用了这段语句块
哪个负责处理这个异常;
五. 异常层级关系
所有异常类的祖先类为java.lang.Throwable类。它有两个直接的子类:
1. Error类:表示仅靠程序本身无法恢复的严重错误,比如内存空间不足,或者Java虚拟机的方法调用栈溢出。在大多数情
况下,遇到这样的错误时,建议让程序终止。
2. Exception类:表示程序本身可以处理的异常。Exception还可以分为两种:运行时异常和受检查异常。
a. 运行时异常
1) 基本概念
RuntimeException类及其子类都被称为运行时异常,这种异常的特点是Java编译器不会检查它,也就是说,当程序中
可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws子句声明抛出它,还是会编译通过。例
如divide()方法的参数b为0, 执行a/b操作时会出现ArithmeticException异常,它属于运行时异常,Java编译器不会
检查它。
public int divide(int a, int b) {
return a/b; //当参数b为0, 抛出ArithmeticException
}
2) 深入解析
运行时异常表示无法让程序恢复运行的异常,导致这种异常的原因通常是由于执行了错误操作。一旦出现了错误操作,
建议终止程序,因此Java编译器不检查这种异常。
运行时异常应该尽量避免。在程序调试阶段,遇到这种异常时,正确的做法是改进程序的设计和实现方式,修改程序
中的错误,从而避免这种异常。捕获它并且使程序恢复运行并不是明智的办法。
3) 对比
与Error类相比:
相同点:i. Java编译器都不会检查它们;
ii.当程序运行时出现它们, 都会终止程序;
不同点:i. Error类及其子类表示的错误通常是由Java虚拟机抛出的,在JDK中预定义了一些错误类,比如
OutOfMemoryError和StackOutofMemoryError。
RuntimeException表示程序代码中的错误;
ii.Error类一般不会扩展来创建用户自定义的错误类;
RuntimeException是可以扩展的,用户可以根据特定的问题领域来创建相关的运行时异常类;
b. 受检查异常。
除了RuntimeException及其子类以外, 其他的Exception类及其子类都属于受检查异常(Checked Exception)。 这种
异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常时,要么用try...catch语句捕获它,要
么用throws子句声明抛出它,否则编译不会通过。
六. 一些未检查的异常RuntimeException
1. java.lang.ArithmeticException
算术异常 如:除0;
2. java.lang.NullPointerException
空指针引用 如:没初始化一个References便使用;
3. java.lang.ArrayIndexoutofBoundsException
数组越界 如:调用一个有十个元素的Array的第十一个元素的内容;
4. java.lang.NumberFormatException
数据格式异常 如:Integer.parseInt("a");
5. java.lang.NegativeArraySizeException
创建大小为负的数组异常
三. finally语句: 任何情况下都必须执行的代码
由于异常会强制中断正常流程,这会使得某些不管在任何情况下都必须执行的步骤被忽略,从而影响程序的健壮性。
例如小王开了一家小店,在店里上班的正常流程为:打开店门、工作8个小时、关门。异常流程为:小王在工作时突然
犯病,因而提前下班。例:
public void work() {
try {
开门();
工作8个小时();
关门();
} catch(Exception e) {
//异常处理语句
}
}
假如小王在工作时突然犯病,那么流程会跳转到catch代码块,这意味着关门的操作不会被执行,这样的流程显然是不
安全的,必须确保关门的操作在任何情况下都会被执行。finally代码块能保证特定的操作总是会被执行,它的形式如下:
public void work() {
try {
开门();
工作8个小时();
} catch(Exception e) {
//异常处理语句
} finally {
关门();
}
}
当然finally代码块中代码也可位于catch语句块之后,例如:
public void work() {
try {
开门();
工作8个小时();
} catch(Exception e) {
//异常处理语句
}
关门();
}
这在某些情况下是可行的,但不值得推荐:
a. 把与try代码块相关的操作孤立开来,使程序结构松散,可读性差;
b. 影响程序的健壮性。假设catch语句块中继续有异常抛出,关门动作便不会执行。
四. 异常调用栈
异常处理时所经过的一系列方法调用过程被称为异常调用栈。
1. 异常的传播
哪个调用,哪个处理;
a. 异常情况发生后,发生异常所在的方法可以处理;
b. 异常所在的方法内部没有处理,该异常将被抛给该方法调用者,调用者可以处理;
c. 如调用者没有处理,异常将被继续抛出;如一直没有对异常处理,异常将被抛至虚拟机;
2. 如果异常没有被捕获,那么异常将使你的程序将被停止。
异常产生后,如果一直没有进行捕获处理,该异常被抛给虚拟机。程序将被终止。
3. 经常会使用的异常API
getMessage:获得具体的异常出错信息,可能为null。
printStatckTrace():打印异常在传播过程中所经过的一系列方法的信息,简称异常处理方法调用栈信息;在程序调试
阶段,此方法可用于跟踪错误
异常处理语句的语法规则:
1. try代码块不能脱离catch代码块或finally代码块而单独存在。try代码块后面至少有一个catch代码块或finally代码块。
2. try代码块后面可以有零个或多个catch代码块,还可以有零个或至多一个finally代码块。如果catch代码块和finally代码
块并存,finally代码块必须在catch代码块后面。
3. try代码块后面可以只跟finally代码块。
4. 在try代码块中定义的变量的作用域为try代码块,在catch代码块和finally代码块中不能访问该变量。
5. 当try代码块后面有多个catch代码块时,Java虚拟机会把实际抛出的异常对象依次和各个catch代码块声明的异常类型匹配,
如果异常对象为某个异常或其子类的实例,就执行这个catch代码块,而不会再执行其他的catch代码块。
6. 如果一个方法可能出现受检查异常,要么用try...catch语句捕获,要么用throws子句声明将它抛出。
7. throw语句后面不允许紧跟其它语句,因为这些语句永远不会被执行。
try catch finally throws throw:主动抛异常
八. 编写自己的异常
在特定的问题领域,可以通过扩展Exception类或RuntimeException类来创建自定义的异常。异常类包含了和异常相关的信息,
这有助于负责捕获异常的catch代码块,正确地分析并处理异常。
File类
File类提供管理文件或目录的方法。File实例表示真实文件系统中的一个文件或者目录。
1. 构造方法
a/b
a/b/c/d
. File(String pathname): 参数pathname表示文件路径或者目录路径;
. File(String parent, String child): 参数parent表示根路径,参数child表示子路径;
. File(File parent, String child): 参数parent表示根路径,参数child表示子路径;
只处理一个文件,使用第一个构造方法;如处理一个公共目录的若干子目录或文件,那么使用第二个或者第三个更方便。
2. 普通方法
. boolean createNewFile():创建一个新的文件,如果文件已经存在,则创建失败(返回false),否则创建成功(返回true)。
. boolean delete():删除文件或者空目录
. boolean mkdir()/mkdirs():创建一个或者多个目录(连续创建)->如果该目录的父目录不存在话,那么还会创建所有的父目录;
. boolean canRead()/canWrite():判断指定的文件是否能读取或者写入数据
. boolean exists():判断指定的文件或者目录是否存在
. String[] list():返回指定目录下所有文件名或者子目录名所组成的字符串数组
. boolean isFile():判断文件是不是一个标准文件
. boolean isDirectory:判断文件是不是一个目录
. long lastModified():返回指定文件最后一次被修改的时间(从1970年1月1日凌晨12点到这个文件的修改时间
之间所经历的毫秒数)
. String getPath()/getAbsolutePath():返回指定文件或者目录的路径和绝对路径
. String getCanonicalPath(): 获取该File对象所代表的文件或者目录的正规路径
. String getParent()/getName():返回指定文件或者目录的父目录(没有返回null)和名字
一. 流的概念
程序的主要任务是操纵数据。在Java中,把一组有序的数据序列称为流。根据操作的方向,可以把流分为输入流和
输出流两种。程序从输入流读取数据,向输出流写出数据。
文件 输入流 输出流 文件
内存 -------------> Java程序 ------------------> 内存
键盘 控制台
数据源 数据目的地
数据从硬盘到内存,从内存到硬盘,从内存角度定义输入输出,内存到硬盘,输出;硬盘到内存,输入
服务server 发送[输出]
客户client 接受[输入]
Java I/O系统负责处理程序的输入和输出,I/O类库位于java.io包中,它对各种常见的输入流和输出流进行了抽象。
如果数据流中最小的数据单元是字节,那么称这种流为字节流;如果数据流中最小的数据单元是字符,那么称这种流
为字符流。在I/O类库中,java.io.InputStream和java.io.OutputStream分别表示字节输入流和字节输出流,
java.io.Reader和java.io.Writer分别表示字符输入流和字符输出流。
输出与输入
字节与字符
二. 字节输入流和输出流概述
在java.io包中,java.io.InputStream表示字节输入流,java.io.OutputStream表示字节输出流,它们都是抽象类,不
能被实例化。
InputStream类提供了一系列和读取数据有关的方法:
1. read(): 从输入流读取数据:有三种重载形式:
fis.read():读一个字节,读到的字节作为返回值
new String(by[],0,len)
fis.read(byte[] by):读最多by.length个字节,读到的字节保存在by数组中,返回值:真正读到了多少个字节
fis.read(by,begin,len):读最多len个字节,读到的字节保存在by数组中,从索引为begin处开始保存,by:begin,返回值就是真正读取到的字节数量
a. int read(): 从输入流读取一个8位的字节,把它转换为0-255之间的整数,并返回这一整数
b. int read(byte[] b): 从输入流读取若干个字节,把它们保存到参数b指定的字节数组中。返回的整数表示读取的
字节数。如果遇到输入流的结尾,则返回-1;
c. int read(byte[] b, int off, int len): 从输入流读取若干个字节,把它们保存到参数b指定的字节数组中。
返回的整数表示读取的字节数。参数off指定在字节数组中开始保存数据的起始下标,参数len指定
读取的字节数目。返回的整数表示实现读取的字节数。如果遇到输入流的结尾,则返回-1;
以上第一个read方法从输入流读取一个字节,而其余两个read方法从输入流批量读取若干字节。在从文件或键盘读数据
时,采用后面两个read方法可以减少进行物理读文件或键盘的次数,因此能提高I/O操作的效率。
2. void close(): 关闭输入流,InputStream类本身的close()方法不执行任何操作。它的一些子类覆盖了close()方法,
在close()方法中释放和流有关的系统资源。
3. int available(): 返回可以从输入流中读取的字节数目;
4. skip(long): 从输入流中跳过参数n指定数目的字节。
OuputStream类提供了一系列和写数据有关的方法:
1. write(): 向输出流写入数据:有三种重载形式:
a. void write(int b): 向输出流写入一个字节;
b. void write(byte[] b): 把参数b指定的字节数组中的所有字节写到输出流;
[97,92,95,77,81]
by,2,3
c. void write(byte[] b, int off, int len): 把参数b指定的字节数组中的所有字节写到输出流,参数off指定字节
数组的起始下标,从这个位置开始输出由参数len指定数目的字节;
以上第一个write方法从输出流写入一个字节,而其余两个write方法从输出流批量写出若干字节。在向文件或控制台写数据
时,采用后面两个write方法可以减少进行物理读文件或键盘的次数,因此能提高I/O操作的效率。
2. void close(): 关闭输出流,OutputStream类本身的close()方法不执行任何操作。它的一些子类覆盖了close()方法,
在close()方法中释放和流有关的系统资源。
3. void flush(): OutputStream类本身的flush()方法不执行任何操作,它的一些带有缓冲区的子类(比如BufferedOutputStream
和PrintStream类)覆盖了flush()方法。通过带缓冲区的输出流写数据时,数据先保存在缓冲区中,积累到
一定程度才会真正写到输出流中。缓冲区通常用字节数组实现,实际上是指一块内存空间。flush()方法强
制把缓冲区内的数据写到输出流中。
文件输入[字节/字符],文件输出[字节/字符]
示例:
FileInputStream and FileOutputStream
1. 当创建一个FileInputStream对象的时候,文件必须存在以及是可读的FileInputStream(File file)
FileInputStream(String name)
2. 当创建一个FileOutputStream对象的时候,可以创建一个新的文件,也可以覆盖一个已经存在的同名文件。
FileOutputStream(File file)
FileOutputStream(File file, boolean append)
如果要创建的文件已经存在,可以选择向旧文件添加新的内容(append为true)或者新的内容覆盖旧文件的
内容(append为false)。
FileOutputStream(String name)
FileOutputStream(String name, boolean append)
如果要创建的文件已经存在,可以选择向旧文件添加新的内容(append为true)或者新的内容覆盖旧文件的
内容(append为false)。
FileReader and FileWriter
1. 读写字符文件方便
2. 构造器
FileReader(File file)
FileReader(String name)
FileWriter(File file)
FileWriter(String filename)
FileReader:new FileReader(“d:/back/string.txt”) =
new InputStreamReader(new FileInputStream(“d:/back/string.txt”));
FileWriter:new FileWriter(“d:/back/string.txt”) =
new InputStreamWriter(new FileOutputStream(“d:/back/string.txt”));
BufferedInputStream类: 包装流
BufferedInputStream类覆盖了被过滤的输入流的读数据行为,利用缓冲区来提高读数据的效率。BufferedInputStream类先
把一批数据读入到缓冲区,接下来 read()方法只需要从缓冲区内获取数据,就能减少物理性读取数据的次数。
. BufferedInputStream(InputStream in)——参数in指定需要被过滤的输入流。
BufferedReader类
Reader类的read()方法每次都从数据源读入一个字符,BufferedReader带有缓冲区,它可以先把一批数据读到缓冲区内,
接下来的操作都从缓冲区内获取数据,避免每次都从数据源读取数据并进行字符编码转换,从而提高读操作的效率。
BufferedReader的readLine()方法可以一次读入一行字符,以字符形式返回。
. BufferedReader(Reader in): 指定被修饰的Reader类;
InputStreamReader
OutputStreamWriter
:把字节流转换为字符流
PrintStream
PrintWriter既可以包装输出字节流也可以输出字符流
对象的序列化和反序列化
对象的序列化: 把对象写到一个输出流;
对象的反序列化:从一个输入流中读取一个对象;
1. 对象的持久化
2. 仅仅是一个对象的数据被序列化(将对象的数据序列化成字节流)
3. 要序列化的对象必须实现java.io.Serializable接口,如果有引用类型成员变量,成员变量也需要实现Serializable
对象的序列化主要用于:
1. 网络中传输的是字节流的数据,网络中对象的传输,是将对象的数据经过序列化后转换成字节流。
2. 将对象数据序列化到文件中,将对象数据转换成字节流存储到文件中。
从文件中读取字节流数据并转换成对象叫做对象的反序列化。
ObjectInputStream 和ObjectOutputStream(对象输入和输出流,可以读写基本数据类型和对象)
1. ObjectInputStream 和ObjectOutputStream为应用程序提供对象的持久化存储
2. 一个ObjectInputStream 可以反序列化通过ObjectOutputStream写入的基本数据类型和对象
3. 构造器
ObjectInputStream(InputStream in)
ObjectOutputStream(OutputStream out)
4. 方法
readObject()/writeObject() 将对象写入到输出流中或者从输入流中读取对象
反射:Reflect
类的加载:
当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过加载、连接、初始化3个步骤来对类进行初始化,这个过程称为类加载或者类初始化。
类加载指的是将类的class文件读入内存,并为之创建一个java.lang.Class对象,也就是说,当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象。
[每个类是一批具有相同特征的对象的抽象,而系统中所有的类实际上也是实例,它们都是java.lang.Class的实例]
每个类在加载之后,系统会为该类生成一个对应的Class对象,通过该Class对象就可以[在运行的时候]访问到虚拟机中的这个类的相关信息。获取Class对象的方式如:
1)已知类的全限定名
Class.forName(String clazzName)
2)已知某个类的类型,调用其class属性,如Person类
Person.class
3)已有某个类的对象
obj.getClass()
一旦获得某个类所对应的Class对象之后,系统就可以调用Class对象的方法来获得该对象和该类的真实信息了。
如:
获取构造器
getConstructor(Class>... paraTypes):返回此Class对象对应类的指定参数列表的public的构造器
getConstructors():获取对应类所有public的构造器
getDeclaredConstructor(Class>... parasType):获取对应类中声明的指定参数列表的构造器,与访问权限无关
getDeclaredConstructors():获取对应类中所有的构造器,访问权限无关
[确定一个构造器,需要用参数列表类型确定]
获取方法:
getMethod(String name,Class>... paraTypes):返回指定方法名,对应参数列表的public方法
getMethods():返回所有public方法
getDeclaredMethod(String name,Class>... paraTypes):返回指定方法,与访问权限无关
getDeclaredMethods():返回所有方法,与访问权限无关
[确定一个方法,除了方法名外,还需要参数列表类型]
获取属性:
getField(String name):返回对应类指定的public Field
getFields():返回对应类的所有public Field
getDeclaredFiled(String name):返回对应类的指定Field,与Field的访问权限无关
getDeclaredFileds():返回对应类的指定所有Field,与Field的访问权限无关
获取此Class对象对应类所继承的父类,实现的接口、修饰符、所在包、类名等信息等
getInterfaces()
getSuperclass()
getModifiers()
getPackage()
getName()
getSimpleName()
Declared:当前类中声明的所有的
没有declared:所有的public的。包含从父类继承的。
使用反射创建与操作对象
通过Method类型对象执行对应方法,通过Constructor对象调用对应构造器创建实例,通过Field对象访问并修改对象属性。
创建对象
1)通过Class对象,执行默认无参构造器
Clazz.newInstance();
[常用,很多框架都会使用]
2)获取Constructor对象,调用Constructor对象的newInstance()方法来创建指定对象
constructor.newInstance(Object... params)
调用方法
使用获取到的Method对象,调用方法:
Object invoke(Object obj,Object... args):obj是执行方法的主调,args是方法执行的实参数据列表
访问操作属性
通过获取到的Filed可以获取或者设置Filed值
1)getXxx(Object obj):获取obj对象的该Filed属性值
Xxx对应8个基本类型,如果获取的属性为引用类型,直接写get(Object obj)
2)setXxx(Object obj,Xxx val):将obj的该Filed设置为val值
Xxx对应8个基本类型,如果获取的属性为引用类型,直接写set(Object obj,Xxx val)
遇到私有的属性可通过反射取消权限检查,如:
xxFiledObj.setAccessible(true);
反射和泛型:
如String.class的类型实际上是Class,如果Class对应的类暂时未知,则使用Class>,通过在反射中使用泛型,可以避免使用反射方法生成的对象需要强制类型转换.
如以下代码:
public static Object getInstance(String clsName){
Class cls = Class.forName(clsName);
return cls.newInstance();
}
获取对象后需要类型强制转换
public static T getInstance(Class cls){
return cls.newInstance();
}
获取对象后无需类型转换
corejava:接口,IO流,网络,String拆分split,截取subString
..
数据库:JDBC:
mybatis:
基本概念:
1、计算机网络
计算机网络是相互连接的独立自主的计算机的集合,可以把分布在不同地理区域的计算机与专门的外部设备用通信线路连接一个规模大、功能强的网络系统
最简单的网络形式由两台计算机组成。
2、网络通信
IP地址:
1)IP网络中每台主机都必须有一个惟一的IP地址;
2)IP地址是一个逻辑地址;
3)因特网上的IP地址具有唯一性,用于唯一标识网络中的一个通信实体
4)32位,4个字节,通常分为4个8位的二进制数,常用点分十进制的格式表示,例如:192.168.0.16。
8位:11111111:255
…
127.0.0.1
172.16.7.250
ip地址用于唯一标识网络中的一个通信实体,但是一个通信实体可以有多个通信程序同时提供网络服务,所以此时还需要使用端口
http://ip:port/resourceName:统一资源定位符
url:…@localhost:1521
端口号:
端口使用一个16位的数字来表示,它的范围是0–65535,1024以下的端口号保留给预定义的服务。不同的应用程序处理不同端口的数据,同一台机器不能有两个程序使用同一个端口号,例如:http使用80端口,Oracle 数据库,默认的端口号为1521;TOMCAT,默认的端口号为8080;
如果把IP地址理解为某个人所在的街道,那么只有街道地址还是找不到这个人,我们还需要知道这个人的门牌号,就类似端口。
比如计算机之间发送数据,计算机网络充当邮递员,当一个程序需要发送数据时,需要指定目的地的IP和端口,指定了正确的IP地址和端口号,通信双方建立连接,就可以发送接收数据了。
协议:
1)为进行网络中的数据交换(通信)而建立的规则、标准或约定;(=语义+语法+规则) ;
TCP:面向连接的可靠的传输协议;在利用TCP协议进行通信的时候,首先要建立起通信双方的连接,一旦连接建立后就可以通信了。TCP协议提供数据确认和重传的机制,保证数据一定能够到达数据接收端。像打电话。
基于TCP的Socket编程步骤:
TCP协议会在通信的两端建立一个Socket,从而在通信两端之间形成网络链路,java中使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信.在两个通信实体没有建立虚拟链路之前,必须有一个先做出“主动姿态”,主动接受来自其他通信实体的连接请求,作为服务端。
java中能接收其他通信实体请求的类是ServerSocket,ServerSocket用来监听来自客户端连接请求的方法
accept():如果接收到一个客户端Socket的连接请求,该方法将返回一个与客户端Socket对应的Socket,否则该方法将一直处于等待阻塞状态,直到接收到客户端连接请求
ServerSocket server = new ServerSocket(8888);
//server端建立起主动姿态:等待客户端请求链接
Socket socket = server.accept();
Socket socket = new ServerSocket(8888);
socket.getInputStream():读
socket.getOutputStream():写
对于客户端可通过构建Socket对象来连接到指定服务器:
Socket socket = new Socket("127.0.0.1", 8888);
socket.getOutputStream()
socket.getInputStream();
节点流:文件流 FileInputStream 键盘输入
网络:socket
包装流/处理流:IO
BufferedInputStream
BufferedPutPutStream
InputStreamReader
OutputStreamWriter
PrintStream
PrintWriter
ObjectInputStream
ObjectOutputStream
RandomAccessFile:随机读取流
DataInputStream
管道流.....
当客户端、服务端产生对应的Socket后,连接建立,就无需再区分服务端客户端了,相互之间通信即可。Socket提供了两个方法获取输入流和输出流
getInputStream():获取输入流,读数据
getOutputStream():获取输出流,写数据
所以,不论底层的IO流是文件流还是网络流等,程序都可以使用包装流进行处理,从而提供更多更方便的处理。
1)服务器程序编写:
①调用ServerSocket(int port)创建一个服务器端套接字,并绑定到指定端口上;
②调用accept(),监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字;
③调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收;
④最后关闭通信套接字。
2)客户端程序编写:
①调用Socket()创建一个流套接字,并连接到服务器端;
②调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收;
③最后关闭通信套接字。
String:
split,SubString()
Integer:
parseInt(String s,int radix)
Timestamp:
Timestamp t = new Timestamp(毫秒数)
IO:
skip,seek
Properties:
load,getProperty,put
JDBC:
prep.addBatch();prep.executeBatch()