JAVA学习笔记
一 JDK安装
1.1环境变量配置
1.1.1 永久配置环境变量
打开方式:计算机-高级-环境变量
JAVA_HOME:自己建的系统变量,添加到JDK目录即可 //切记,不是用户变量
path:系统默认环境变量,添加两个bin文件,jdk\bin和jdk\jre\bin
classpath:执行class文件时,指定优先搜索java类的存放路径
1.1.2 临时配置环境变量
JAVA_HOME:自己建的系统变量 //切记,不是用户变量
path:系统默认环境变量
set path //查看环境变量
setpath=d:\hello;%path% //设置环境变量,只在当前cmd窗口有效,关闭后不影响path原来值,帮助:helpset
classpath:执行Java程序时,优先搜索java类的存放路径
setclasspath=d:\hello //只在指定路径下搜索java类程序
setclasspath=.;d:\hello //只在指定路径下(当前路径和d:\hello两个)搜索java类程序,推荐使用此种方式
setclasspath=d:\hello; //优先在classpath指定路径下搜索,然后在当前路径搜索,一般不适用此种方式
1.1.3 JDK安装成功验证及DOS编译、执行
DOS下执行:
javac
javac -version //查询java版本:
DOS下java程序的编译、执行:
编译:javac hello.java // 编译完后,生成hello.class文件,即可执行文件
执行:java hello //执行编译过后的hello类,类名尽量和文件名一致,方便运行
二 JAVA基础
1.1 关键字修饰符
1.1.1public
公有,权限最大
权限修饰符,可修饰类、属性、方法,
全局都可被使用此类、属性、方法。
1.1.2 private
权限修饰符,用于修饰成员(成员变量、成员函数)。
私有内容只在本类中有效。
修饰方法时,不存在覆盖。
注意:子父类覆盖
子类覆盖父类方法时,子类方法权限必须大于或等于父类方法权限
子类或父类方法要么同时用static修饰,要么都不被static修饰
1.1.3 static (07)
修饰符,用于修饰成员(属性和方法);
static所修饰的成员,被所有对象所共有;
static优先于对象存在,因为static成员随类的加载就存在了;
static所修饰的成员,能够被类名直接调用,类名.静态成员名;
static所修饰的数据是共享数据,对象中的存储是特有数据;
1.1.4 final (09 04)
final可以修饰类,方法,变量;
final修饰的类不可以被继承;finalclass Fu;
final修饰的方法不可以被覆盖;
final修饰的变量是一个常量,只能被赋值一次。
内部类只能访问被final修饰的局部变量。
1.1.5 void:
权限修饰符,可修饰方法;
1.2 关键字、标识符、注释
关键字:赋予特殊java含义的单词,全部小写;
public
标识符:程序中自定义的一些名称
字母,数字、_、$组成,不支持空格;
数字不可以开头;
不可以使用关键字;
如:类名HelloJava
注释:解释说明代码中的文字,调试也能用到
单行注释://单行注释内容 # 可以嵌套注释
多行注释:/*多行注释内容*/
文档注释:/**文档注释*/ # 注释中的内容可以通过java工具javadoc提取出来,生成一个网页文件,包括说明文字和代码。java特有!
注释的应用:
1.3 基本数据类型及转换
常量:不能改变的数据
"字符串",'字符',""空字符串,null啥都没有
进制:二、八、十、十六进制
变量:内存中的一块存储区域
定义变量:先定义后使用
类型 变量名 = 初始化值;
int a = 2;
强制类型转换:
(int)(a+b)
1.4 运算符
算数:+、-、*、/、%、++、--、
赋值:=、+=、-=、*=、/=、%=
比较:>、<、>=、<=、==、!=,结果为true或false
逻辑:&、|、!、^、&&(短路)、||(短路)
位:<<、>>、>>>(无符号右移)、&、|、^、~(取反) // 转化为二进制后参与运算
举例:3<< 2 // 左移两位
三元:(条件表达式)?表达式a:表达式b; #条件表达式为true时,执行表达式a,否则执行表达式b
举例:
a =(x>y)?x:y;
1.5 程序流程控制
顺序结构:子上而下顺序结构执行
判断结构:if语句
选择结构:switch语句
循环结构:while、do...while、for
1.5.1判断结构if-else
if(条件1)
{}
----------------
if(条件2)
{}
else
{}
-----------------
if(条件3)
{}
else if(条件4) //else if()可有多个
{}
else
{}
1.5.2 选择结构switch
switch(表达式)
{
case 取值1: //case后不需要使用{}
执行语句;
break;
case 取值2:
执行语句;
break;
case 取值3:
执行语句;
break;
......
default:
执行语句;
break;
}
1.5.3 循环结构while、do…while、for
while(条件)
{
语句
}
----------------
do
{
执行语句
}
while(条件); # 不要忘记while后面的';'
----------------
for(初始化表达式;循环条件;循环后的操作表达式)
{
执行语句;
}
----------------
for(type element: array)
{
System.out.println(element);
}
1.5.4 if和switch区别
if:使用较多
1)对具体的值进行判断
2)对区间进行判断
3)对运算结果是boolean类型的表达式进行判断
switch:使用较少
1)对具体的值进行判断
2)值的个数相对较少,且固定
对于几个固定的值判断,建议使用switch语句,因为switch语句会将具体的答案都加载进内存,效率相对高一点。
1.5.5 局部代码块
在主函数中,作用是:可以定义局部变量的生命周期。
eg:
{
int a =1; // 局部变量,a离开此局部代码块,就不能被使用了,因为代码块执行完之后,就被释放了。
语句......;
}
1.5.6 break、continue
break适用范围:switch和循环语句中
break:1、直接跳出所在的当层循环语句,开始执行当层循环下面的语句;如果出现了循环嵌套
2、Java中循环标号后可跳出指定循环
eg:
biaohao1:for(;;)
{
biaohao2:for(;;)1
{
执行语句;
break biaohao1; //通过标号,直接跳出两层循环。
}
}
continue适用范围:循环语句中
continue:跳过本次循环continue之后的语句,继续下次循环
1.6 函数(方法)
定义在类中的具有特定功能的一段独立小程序;可以提高代码的复用性;和主函数同级,没有嵌套函数的说法。
函数格式:
修饰符 返回值类型 函数名(参数类型1参数1,参数类型2 参数2,...)
{
功能语句;
return 返回值;
}
函数的两个明确:
1、这个功能的结果是什么? 确定返回值
2、这个功能实现过程中是否需要未知内容参与运算? 确定参数列表
----------------------------------------------------------------
1.6.1 函数重载
条件:
同一个类;
同名;
参数列表中参数个数或参数类型不同;
注意:函数重载和返回值类型无关;
Java是严谨性语言,不允许出现函数调用的不确定性,会编译失败。
----------------------------------------------------------------
1.7 数组
一维、二位数组、排序算法
一维数组定义:
元素类型[] 数组名 = 元素类型[元素个数或数组长度];
注意:数组一旦建立,必须明确其长度;
格式1:需要一个容器,但是不明确容器的具体数据。
int[] a = new int[5];
a[]
格式2:需要一个容器,存储一致的具体数据。
int[] a = new int[]{1,2,3,4,5};
格式3:需要一个容器,存储一致的具体数据。
int[] a = {1,2,3,4,5};
二维数组:
格式一:指定二维和一维数组的长度
int[][] shuZu = new int[5][3];
格式二:指定二维的长度,不指定一维数组的长度
int[][] shuZu = new int[5][];
1.8 JVM内存空间
1、寄存器
cpu相关的
2、本地方法区
所在系统相关的
3、方法区
4、栈内存
存储的都是局部变量,变量所属的作用域一旦结束,该变量就自动释放。
5、堆内存
存储的是数组和对象(其实数组就是对象),凡是new就简历在堆中。
特点:
1、每一个实体都有首地址值;
2、堆内存中的每一个变量都有默认初始化值,更具类型的不同而不同,整数是0,小数0.0,boolean是false。
3、垃圾回收机制。
三 面向对象
1.1面向对象基本概念
面向对象的特征:
封装、继承、多态
类与对象的关系?
类:对事物的描述,用java语言对显示生活中的事物进行描述,通过类的形式来体现的。
怎么描述呢?
对事物描述通常只关注两方面:属性,方法;
只要明确该事物的属性和行为并定义在类中即可;
对象:该类事物实实在在存在的个体,即类的实例;对象一般都是名词;
Java中通过new来创建; // new实际上是用来开辟一块,指定类型的空间
eg:
class car //定义一个类
{
成员变量; // 属性
成员函数; // 行为
}
new car // 创建对象
car baoma = new car // 创建一个被baoma应用的对象,给对象起个名字
baoma.成员变量名 // 调用成员变量
baoma.成员函数名() // 调用成员函数
1.1.2 成员变量和局部变量的区别
成员变量:定义在类中,整个类中都可以访问;
存在于堆内存的对象中;
随着对象的创建而存在,随着对象的消失而消失;
都有默认初始化值;
局部变量:定义在函数、语句、局部代码块中,只在所属的区域有效;
存在于栈内存的方法中;
随区域的存在而存在,区域结束而结束;
没有有默认初始化值;
1.1.3 匿名对象
即没有名字的对象,当只对对象的方法进行过一次调用的时候使用
new Car(); //即匿名对象,
new Car().run(); //匿名对象调用函数
Car c = new Car() // 有名的对象
面向对象第一个特征:封装,用于隐藏细节
private,数据私有化只是实现封装的方式之一;
private:私有,是一个权限修饰符,权限最小,public权限最大,用于修饰成员,私有的内容只在本类中有效。
privateint age;
publicvoid setage(int a)
{}
publicvoid getage(int a)
{}
1.2 构造函数
构造函数:构建创造对象时调用的函数,可以给对象初始化;
如果类中没有定义过构造函数,那么该类中会有一个默认的空参数构造函数;
如果类中已经定义过构造函数,那么该类中的默认的构造函数就没了;
构造函数
特点:
1、函数名与类名相同;
2、不用定义返回值类型;
3、没有具体返回值;
作用:对对象进行初始化
class Person
{
Person() //构造函数名必须与类名一致
{
......;
}
}
Person zhangsan = new Person(); //在创建对象时,自动回调用执行构造函数Person()
一般函数和构造函数的区别?
构造函数:
在对象创建时,就会调用与之对应的构造函数,对对象进行初始化;
在对象创建时,只调用一次;
一般函数:
对象创建后,需要函数功能时才调用;
对象创建后,可根需要调用多次;
this关键字:代表当前对象
使用1:
this就是所在的函数所属对象的引用;
简单说:哪个对象调用了this所在的函数,this就代表哪个对象;
使用2:
使用this可以用于在构造函数中,调用其他构造函数,注意:只能定义在构造函数的第一行,因为初始化动作需要先执行。
1.1 子父类实例化过程(09 03)
person p = person();
1、JVM会读取指定的路径下的person.class文件,并加载进内存,并会先加载person的父类(如果有直接的的父类的情况下);
2、在堆内存中的开辟空间,分配地址;
3、并在对象空间中,对对象中的属性进行默认初始化;
4、调用对应的构造函数进行初始化;
5、在构造函数中,第一行会先到调用父类中构造函数进行初始化;
5、父类初始化完毕后,在对子类属性进行显式初始化;
7、再进行子类构造函数的特定初始化;
8、初始化完毕后,将地址赋值给应用变量;
子父类实例化加载图解
1.2 抽象类(09 06)
abstract class ClassName{
abstractvoid funcName();
}
1、方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中,该类必须也被abstract修饰;
2、抽象类不可以被实例化,为什么?因为调用抽象方法没意义;
3、抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化,否则,这个子类还是抽象类;
抽象类和一般类的异同点
相同点:抽象类和一般类都是用例描述事物的,都在内部定了成员
不同点:
1、一般类有足够的信息描述事物,抽象类描述事物的信息有可能不足;
2、一般类中不能定义抽象方法,只能定义飞抽象方法,抽象类中可以定义抽象方法,同时也可以定义非抽象方法;
3、一般类可以被实例化,抽象类不可以被实例化;
抽象类一定是父类吗?
是的,因为需要子类覆盖其方法后才可以对子类实例化;
1.2 接口(09 09)
当一个抽象类中的方法都是抽象类的时候,这是就可以将该抽象类用另一个形式定义和表示,就是接口interface;
接口的定义关键字是interface,不是class
对于接口当中常见的成员;而且这些成员都有固定的修饰符(系统会自动加上)
1、全局常量,public staticfianl
2、抽象方法,public abstract
由此得出结论,接口中的成员都是公共的权限。
interface Demo
{
publicstatic final int value = 4; //加黑处为系统固定加的
publicabstract void show1(); //
publicabstract void show2(); //
}
实现:相当于继承的extends
class DemoZi implementsDemo{ //实现
}
类与类直接是继承关系;类与接口之间是实现关系;
接口不可以实例化。
只能有实现了接口的子类并覆盖了接口中所有的抽象方法后,该子类才可以实例化,否则这个子类就是抽象类。
多实现:Java中不允许多继承,但允许多实现
class DemoZi implementsDemo,Demo1{ //多实现
}
在Java中不直接支持多继承,因为会出现调用的不确定性,所以java将多继承机制进行改良,在Java中变成了多实现。
一个类在继承另一个类的同时,还可以实现多个接口
classDemoZi extends Fu implements Demo1,Demo2{ //继承一个类,并且实现多个接口
}
接口与接口之间是继承关系(而且可多继承);类与类(抽象类)之间是继承关系;类与接口之间是实现关系。
接口特点:
对外暴露规则;
程序功能扩展;
降低耦合性;
可以用例多实现;
抽象类和接口的区别:
相同点:都是不断向上抽取而来的;
不同点:
抽象类需要被继承,而且只能单继承;接口需要被实现,而且可以多实现;
抽象类中可以定义抽象类方法和非抽象方法,子类继承后,可以直接使用非抽象方法;接口中只能定义抽象方法,必须有子类去实现;
抽象类的继承,是is a关系,在定义该体系的基本共性内容;
接口的实现是like a关系,在定义体系额外功能。
1.3 多态(10 02)
多态:某一类事物的多种形态
举例:猫种类事物即具备猫的形态,,又具备着动物的形态,这就是对象的多态性。
简单说:就是对象对应着不同类型。
多态在代码中的体现:
父类或者接口的引用指向其子类的对象。一个对象两种形态
多态的好处:
提高了代码的扩展性,前期定义的代码可以使用后期的内容
多态的弊端:
前期定义的内容不能使用(调用)后期子类的特有内容。
多态的前提:
1、必须有关系,继承,实现。
2、必须有覆盖。
多态转型:
向上转型:猫类型的猫,转为动物类型;Animal a = new Cat()
向下转型:动物类型的猫对象,转为猫类型;Cat b = (Cat)a
如果还想用具体动物猫的特有功能,可以将该对象进行向下转型,使用子类的特有方法。
注意:对于转型,自始至终都是子类对象在做着类型的变化
判断对象是何种类:
animala = new cat();
if(a instanceof cat)//为真
if(a instanceof dog)//为假
if(a instanceof animal)//为真
1.3.1 多态时,成员编译和运行的特点
1、成员变量
编译时,参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败;
运行时,参考引用型变量所属的类中的是否有调用过的成员变量,并运行该所属类中的成员变量;
简单地说,编译和运行都参考等号左边。
2、成员函数(特殊)
编译时,参考应用型变量所属的类中的是否有调用的成员函数,有,编译通过,没有,编译失败;
运行时,参考对象所属的类中的是否有调用过的函数,并运行该所属类中的成员函数;
简单地说,编译看左边,运行看等号右边。
3、静态函数
编译时,参考应用型变量所属的类中的是否有调用的静态方法,有,编译通过,没有,编译失败;
运行时,参考引用型变量所属的类中的是否有调用过的静态方法,并运行该所属类中的静态方法;
简单地说,编译和运行都参考等号左边。
1.4 内部类
类的位置定义在类中。
内部类的访问特点:
1、 内部类可以直接访问外部类中的成员;
2、 外部类要访问内部类,必须建立内部类的对象;
一般用于类的设计:分析食物是,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容;这时就是还有的事物定义成内部类来描述。
class Outer{
classInner{ //内部类
}
}
内部类的创建:
Outer.Inner= new Outer().new Inner();
1.4.1 内部类修饰符
private:
static:内部类相当于外部类,Outer.Inner = new Outer.Inner()
如果内部类是静态的,只能访问外部类中的静态成员;
如果内部类中定义了静态成员,则该内部类也必须是静态的;
为什么内部类能直接访问外部类中成员
那是因为内部类持有了外部类的引用,外部类名.this
内部类放在局部位置上
即内部类放在方法内,内部类在局部位置上只能访问局部中被final修饰的局部变量。
1.4.2 匿名内部类
就是内部类的简写格式
必须有前提:内部类必须继承或实现一个外部类或者接口
匿名内部类:其实就是一个匿名子类对象。
四 异常体系
Throwable:无论是error,还是异常,问题发生就应该可以抛出,让调用者知道并处理。
通过两个关键字来体现,throws、throw,被这两关键字曹锁的列和对象都具有可抛性。
Error:一般不可处理,JVM抛出,直接修改程序。
Exception:可以处理
异常分类:
1、 编译时监测异常:Exception和其子类,除特殊子类RuntimeException体系。
希望调用者对异常做处理
2、 编译时不检测异常(运行时异常):就是Excepton中的RuntimeException和其子类。
调用者调用时出现错误,异常不可做处理,功能无法继续,直接停止程序,需修改程正。
1.1 throws和throw
1、 throws使用在函数上;throws可抛出多个异常类,用逗号隔开;
2、 throw使用在函数内;throw抛出一个异常;
1.2 try …catch异常捕捉
不能处理就抛,能处理就try
对异常进行针对性处理的方式。
具体格式:
try{
需要检测的异常代码
}
catch(异常类 变量){ //变量用来接收发生的异常对象
处理异常的代码
}
finally{
一定会执行的代码
}
1.3 异常处理原则
1、函数内容如果抛出需要检测的异常,那么函数上必须要声明。否则必须在函数内用try catch 捕捉,否则编译失败
2、如果调用到了声明的异常的函数,要么trycatch 要么throws,否则编译失败。
3、try catch和throws什么时候用:
功能内容可以解决,用catch;
解决不了,用throws告诉调用者,由调用者解决。
3、 一个功能如果跑出了多个异常,那么调用时,必须有对应多个catch进行针对性的处理;
内部有几个需要检测的异常,就抛出几个异常,抛出几个就catch几个。
1.4 finally
catch、return执行完后,finally里的语句都会执行;
除了执行退出jvm虚拟机语句 System.exit(0)后,finally不会执行。
1、 try catch finally
2、 try catch ,当没有必要资源需要关闭时,可以不用finally
3、 try finally, 需要throws抛出,异常无法直接catch处理,但是资源需要被关闭。
1.5 异常的注意事项
1、 子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类。
class A extends exception{}
class B extends A{}
class C extends exception{}
2、 如果父类抛出多个异常,那么子类只能抛出父类异常的子集。
简单说:子类覆盖父类只能抛出父类的异常或者子类或者子集。
注意:父类的方法没有抛出异常,那么子类覆盖时绝对不能抛;只能try。
1.6 多catch情况
一般抛几个,就有几个catch处理异常;但是可以使用Excetion接收所有异常,且必须放在最后一个cathc里,否则编译失败。
五 Object类
1.1 equals方法
equals方法复写,重点掌握。
1.2 hashCode方法
equals方法复写时,hashCode方法通常需要复写,以保证相同对象的哈希值相同。
1.3 getclass方法
1.4 toString方法
六 包(package)与修饰符访问范围
1、package 包名; // 创建包,在编译时会自动创建此文件夹。
2、不同包之间的访问:被访问的包中的类必须是public的,被访问的包中的类的方法也必须是public的;
3、protect权限:不同包中,类中的方法如被protect修饰,则其他类必须是此类的子类,才能继承被protcet修饰的方法。
范围\修饰符 public protected default private
同一类中 ok ok ok ok
同一包中 ok ok ok
子类中 ok ok
不同包中 ok
1.1 import 导入
import作用:为了简化类名书写。
导包的原则,用到哪个类,就导入哪个类。
import只能导入类,不能导入包
import packa.Demo
import packa.*
import packa.aaa.*
1.2 jar包
jar:java的压缩包。
打jar包;解压jar包。
运行jar包: java jar包