*跨平台性 ??面向对象 (多继承,指针) 健壮性(垃圾回收,异常处理) 多线程
Java类和类之间的关系
? ? ? ? 继承 ? 关联 ? 依赖
Java面向对象的四个特征(特性)
? ? ? ? 继承 ? 封装 ? 多态 ? (抽象)
JVM (虚拟机):java virtual machine
?内存中开辟一块空间 源文件编译成计算机能识别的字节码文件
JRE? java runtime environment 运行环境 ???JRE里面包含JVM
运行别人写好的java程序
JDK? java development kit 开发工具包 ???JDK里面包含JRE
??????? 开发时需要用到的工具
Win+r 输入cmd指令 开启一个doc窗口
切换盘符 盘符名:回车 ??cd..退一层文件夹 ?cd 文件名(* ? #) 进入文件夹 ?????
配置环境变量 添加jdk/bin到环境变量 doc窗口输入javac
配置path?? 让工具可以在任何的位置都可以用
配置 classPath 不管源文件在哪 生成的class文件都统一的存储在配置的目录下
编译Javac Test.java(源代码文件)? ?执行 java类名(字节码文件)
为了使源文件和生成的字节码文件名一致 加修饰符(public) public class Test (不用class Test)
常量池中的值默认空间大小 ??32bit-int?? 64bit-double
1? 3.4 常量值 存储在常量缓冲区中的
常量值的存储形式不是十进制 是以二进制形式存储
?4整型 ?byte(字节型 -128~127) short(2字节) int(4字节) long(8字节)
当数字范围超过int类型的范围时(-2147483648~2147483647)? long后面定义要加L (long a=2147483648L)
?2浮点型 ??float(4字节 32位)?? double(8字节 64位)
float e=3.4; 会出现错误从double转换到float会有损失 ?float e=3.4F(小写大写都可以)
1字符型 char(2字节 16b)为了以示区分 每一个字符前后各加一个单引号
1布尔型boolean(1b) true false 和0 1不同
int--Integer ? char--Character ? byte--Byte ?float--Float
int value=Integer.parseInt("123"); ?//将字符串转化为int类型
将基本类型类型转化为引用类型最快的是在后面加一个连接符
5+"" --返回一个"5"的字符串类型 ? ?5+5+"5"+5+5---结果是"10555"
数组[ ]??? 类class(抽象类abstract class) 接口interface 枚举enum 注解@interface
字符 char 基本 ‘a’ ‘我’ (里面不能大于一个)
字符串(两个及两个以上的字符) String 引用 “a” “abc” “”?? null(什么也没有)
数组[] ?类class 抽象类abstract class 接口interface 枚举enum 注解@interface
所有的变量空间都存储在栈内存
变量空间可以存储基本数据类型 ?也可以存储引用数据类型
如果变量空间存储的是基本数据类型 ?存储的是值 ?一个变量的值改变 ?另一个不会跟着改变
如果变量空间存储的是引用数据类型 ?存储的是引用(地址) ?一个变量地址对应的值改变 另一个跟着改变
Int a=1;? int b=a;??? b的值从a空间里面拿出来,而不是从常量缓冲区拿来,a空间的值才是从常量缓冲区拿来
byte a=1;? //8bit
int b=a;? //32bit??? (大的里面可以装小的)
基本类型与基本类型之间可以直接转换(自动 强制)
引用类型与引用类型之间可以直接转换(自动 强制—上转型 下转型)
基本类型与引用类型之间不可以直接转换(间接—包装类/封装类)
比较内存空间的大小
都是整型 ?byte a=1; int b=a;//直接转化
int a=1; byte b=(byte)a;//(大空间转小空间不可以直接接受大数据类型的值需要进行强制转化)
都是浮点型
float x=3.4F; double y=x;//自动直接转化
double x=3.4;float y=(float)x;//强制转化
如果发现强制转化之前的数值比较大 强制转化这件事可以执行(可以编译)但是转化后的数值不对(会有损失)
int a=1000; byte b=(byte)a;// 1000转化为二进制后强制转化只保留最后的8bit
?比较精确程度 浮点型精确程度更高 可以直接存放整数 反之需要强制类型转换
任何一个浮点型都可以直接存放一个整型
int a=1;? float b=a;//b=1.0
long a=1; float b=a;//b=1.0 自动直接转化
float a=1.0F; int b=(int)a;//强制类型转化
每一个字符都有一个对应的Unicode码 ?a---97 汉字也能转换
char x=’a’; int y=x; //y=97 自动转换
int x=97; char y=(char)x;//强制类型转换
1.程序在运行过程中 不能再次改变的值
??固定的值 便于程序计算 ex:圆周率3.1415926……
2. 用来代表一个含义
贪吃蛇 1234分别代表上下左右四个方向
String是一个引用数据类型 它的值很特殊 可以简单视为是常量
自己创建一个空间 存储一个值 让他固定起来 不能改变
变量指的是一个内存空间(小容器)
变量空间在创建的时候 必须指定数据类型 变量空间的名字
变量空间 里面只能存储一个内容(值 引用)
变量空间内的内容可以改变
变量如何创建/声明:数据类型 ?变量名字? ?int a;
变量的生命周期(变量在栈内存空间 从声明开始创建出来 用完及回收)
注意: ?
变量是一个空间 可以只创建空间 里面不存放内容。变量空间创建后是没有默认的内容空的。空的变量空间不能拿来使用,如果拿出来使用会出现编译错误。
字母(区分大小写) 数字(0~9不允许开头) 符号(英文符号_ $) 中(不推荐)
类名字 首字母大写 如果两个以上的单词 所有首字母大写
变量名 属性/方法/变量 首字母小写 如果两个以上的单词 之后的首字母大写
包 ?全部字母小写(区分关键字)
静态常量 ?全部字母大写(可以利用_分隔)
所有名字都需要见名知义 为了增强程序的可读性
静态常量? 全部字母大写? 用_分隔 ??BOOKSTORE_ADMIN
注释
// 单行注? ? ? ? ? ? ? /*? */ 多行注释? ? ? ? ? ? ? ?/**? */ 文档注释
用来指明对于操作数的运算方式
按照运算符操作数的数目来进行分类
单目 a++?? 双目 a+b?? 三目 (a>b)?x:y
按照运算符的功能来进行分类
[ + -? *? /? %(取余 取模)? ++(自增) --(自减 )]
x++ //(相当于x=x+1)x空间内的值 自增一个 ???++x//对于x空间内的值来讲 都是一致 最终结果增加一个
int x=1;? int y=x++; //x==2? y==1? ++在变量的后面产生一个备份空间,备份空间的值为1,将1赋值给y,原来x的值变成了2
int x=1;? int y=++x; //x==2? y==2 ?++在变量的前面产生一个备份空间,备份空间的值为2,将2赋值给y
x在进行值交换的时候会产生一个副本空间(备份)
++在变量的前面 先自增后备份 ++在变量的后面 先备份后自增 ?会将副本空间的值赋值给别人
Int a=1; a=a++;? //a==1? 产生一个备份空间里面的值为1,a空间此时变成了2,最后在进行赋值运算,把备份空间的值赋值给a
int a=1;
for(int i=1;i<=100;i++){
a=a++;
} //a==1
int m=1;//2 1 0
int n=2;//3 2 1
int sum=m++ + ++n-n-- - --m+n-- - --m; //m==0,n==1,sum==2
?=赋值符号 ????将=右边的内容(值 引用)存入=左边的变量空间
+=? -=?? *=?? /=?? %=?
short m=1; ?m+=2; //m=3? +=是一个赋值符号可以自动转化
m=m+2;//编译出错 类型从int转化为byte可能会有损失 =后面是一 个表达式不可以直接进行转化需要强制转化m=(byte)(m+2)
x空间---8bit 常量区---32bit
+可以自动提升8bit--32bit所以两个不同空间大小的可以加法运算,但是由于m+2是一个表达式=符号不能自动转化表达式
>? >=?? <??? <=?? !=? ==? (对象 ?instanceof 类)
==比较符号 ?比较==前面和==后面的元素(值 引用)是否一致
比较运算符的最终结果是一个Boolean类型(true/false)
注意:==比变量空间里的内容,基本类型的时候是值,比引用类型的是地址 ?“a”.equals(“b”)比较的是引用类型的值是否相同
逻辑与&(前后两个必须同时满足最终结果才为true)?? 逻辑或| (前后两个只要有一个条件满足最终就为true)? 逻辑异或^(前后两个结果不一致最终结果就是true)?? 逻辑非!(单目运算,将原来的结果取反)
短语与&&? 短路或||
逻辑运算符前后连接的应该是两个boolean类型的结果
(3>2)^(3>5)//true???? (3>2)^(5>3)//false
!(3>2)? //false
(3>4)&&(3>2)? //当前面的值的结果为false 最终肯定为false,短路的是&&之后所有计算结果
如果发生了短路情况,性能比&稍微好一点,短路与不一定提高了性能,只有当前面为false的时候才会发生短路,才会提高性能
逻辑与和短路与从最终的执行结果来看是没有任何区别的
(3>2)&&(3>4) //第一个条件为true,最终肯定为true
注意:计算机中不管是正数还是负数 存储的形式都是以补码形式来存储
八制表示形式以0开头 十六进制表示形式以0X开头
按位与&?? 按位或|?? 按位异或^? 按位取反~(单目)?
按位左位移<<?? 按位右位移>>?? 按位右位移(无符号)>>>
&可以视为逻辑运算 可以视为位运算? ? &&只能当作逻辑运算
如果两个符号都当作逻辑运算符来使用时候如下区别:
&前后两个条件都是true 最终结果就是true
&&短路与 正常情况下&执行结果一致
当前条件为false的时候发生短路 最终结果为false
switch(值){// 值可以为(byte short int char) jdk1.5版本enum 1.7版本String
case 值1:
代码1;
//[break;] 可有可无
case 值2:
代码2;
default:
代码
}//如果switch里面没有break就会执行全部的条件
循环想要执行 需要三个必要条件 ?初始值 ?终点判定条件 ?变化量
for( 1初始值 ; 2终点判定条件 ; 4变化量 ){
3好多好多执行;
}
允许将三个条件都写在()内 ?不是必须
初始值 ;
for( ; 终点判定条件 ; ){
好多好多执行;
变化量 ;
}
break continue ? 循环标记,用来选择终止哪一个循环体
int i=1;
int j=1;
ok:for(;i<=5;i++){
ko:for(;j<=5;j++){
if(j==3){
break ok;
}
System.out.println("哈哈哈");
}
}
数组的定义(声明)
int[] x; ? int x[] ? int []x;三种都可以,一般是第一种形式
静态初始化:有元素有长度
?? ?int[] array={10,20,30,40};
?? ?int[] array; ? ?array=new int[]{10,20,30,40};
?? ?int[] array = new int[]{10,20,30};
动态初始化:有长度没有元素(不是真的没有 默认值)
?? ??? ??? ?int[] array = new int[5];
?? ??? ??? ?整数默认值---0
?? ??? ??? ?浮点数默认值---0.0
?? ??? ??? ?字符型默认值--- ?0---char(默认值看不见的) ?0数字对应的code码(不是空格) ? ? 97-a ?65-A ?48-'0'
?? ??? ??? ?布尔型默认值--- ?false
?? ??? ??? ?引用数据默认值--- null?? ?String[]
取数组中的元素 int value=array[3];(取出数组中的第四个元素)
修改数组中的元素 array[3]=400;
数组的索引从0开始到数组长度-1
数组的遍历
for(int value:array){
? ?System.out.println(value);
?? ?}
char类型的数组可以使用输出语句直接打印输出数组里的元素
array=null;数组不用了,被当作垃圾回收了
int[] x = new int[]{10,20,30};
int[] y = x;
y[0] = 100;
System.out.println(x[0]);//? 100
二维数组内存结构:
int[][] array = new int[3][2];
array[0][0] = 10;
array[0][1] = 20;
array[1] = array[0];
array[0] = new int[4];
array[0][0] = 100;
System.out.println(array[1][0]);//? 10
形参可以理解为是方法执行时的临时变量空间 ?x
实参可以理解为是方法调用时传递进去的参数 ?a
方法调用时会将实参的内容传递给形参
如果内容是基本类型 ?传递的 是值 ? ?形参改变 ?实参不变
如果内容是引用类型 ?传递的 是引用 ?形参改变 ?实参跟着改变
类-----抽象 笼统的概念
? ?属性
?? ??? ?权限修饰符 [特征修饰符] 属性类型 属性名字 [= 值]; ?(如果不写是有默认值)
?? ??? ?属性不存在重写?
? ?方法
?? ??? ?权限修饰符 [特征修饰符] 返回值类型 方法名字 ([参数列表]) [抛出异常] [{方法体}]
?? ??? ?方法重载overload
?? ??? ?一个类中 一组方法 ?名字相同 ?参数列表不同 ?构成方法重载
?? ??? ?参数不同体现在 ?个数 类型 顺序
?? ??? ?动态参数列表使用?
?? ?注意:如果方法中没有写返回值类型,在方法中写一个return相当于结束这个方法
public void add(){
if (3>2) {
System.oue.println(true):
} else {
return;
}
}
权限修饰符 与类名一致的方法名 ([参数列表]) [抛出异常] {方法体}
1.作用 : 用来创建当前类的对象
2.结构和写法 : 没有返回类型 ?有返回值
3.调用 : 通过new关键字
4.特点 : 每一个类都有默认无参数的构造方法 我们自己定义了新的 ?默认的构造方法即被覆盖
? ? ? ? ? ? ?构造方法也存在方法重载
不用特征修饰符修饰构造方法
可以理解为是一个非常特殊的方法
没有修饰符 没有返回类型 没有名字 没有参数
只有一个方法的执行体{}
程序块是在每一次调用构造方法之前都会默认自动执行
程序块没有重载 ?却可以存在多个 ?按照创建的顺序逐一执行
特征修饰符只有static
1.指代词 ?代替的是调用属性/方法时的当前的对象
2.this既然是一个对象 ?可以调用一般属性 可以调用一般的方法
? ? ? ? 放置在类成员的任何位置(四个成员都可以)
? ? ? ? 方法之间来回的调用???
? ? ? ? 写法可以的(编译好用) ?执行可能会产生StackOverflowError 栈溢出错误
3.this也可以调用构造方法 ?this(); //省略了构造方法的名字,因为构造方法的名字和类名一样
? ? ? ? ?将这给代码放在另一个构造方法内 ?需要在第一行
调用父类构造方法:
在子类的构造方法中,可以使用?super
?关键字调用父类的构造方法。这是子类构造方法中的第一个语句,并且必须存在。
class Parent {
Parent() {
System.out.println("Parent Constructor");
}
}
class Child extends Parent {
Child() {
super(); // 调用父类的构造方法
System.out.println("Child Constructor");
}
}
2. 访问父类的受保护或包级私有属性:
如果子类需要访问父类的受保护或包级私有属性,可以使用?super
?关键字。
class Parent {
protected String name = "Parent Name";
}
class Child extends Parent {
public void printName() {
System.out.println(super.name); // 访问父类的受保护属性
}
}
3. 调用父类的方法:
如果子类需要调用父类的方法,可以使用?super
?关键字。这可以在子类方法内部进行,或者在重写的方法内部进行。
class Parent {
public void display() {
System.out.println("Parent display");
}
}
class Child extends Parent {
public void display() {
super.display(); // 调用父类的方法
System.out.println("Child display");
}
}
4. 访问父类的静态变量和方法:
使用?super
?关键字可以访问父类的静态变量和方法。这在子类中访问父类的静态成员时很有用。
区别:
?? ?this和super都是指代词 ?代替的是对象
?? ?this代替的是当前执行方法时的那个对象 ?不一定是当前类的(当父类和子类里面有一样的方法(一般方法)时,在父类里面
? ? ? ? ? ?调用这个方法时,执行的是子类的方法,不是父类的) ? ? ?在父类里面调用其他重载的构造方法时,还是使用this调用
?? ?super代替的是当前执行方法时的对象的父类对象 ?空间内部的那个
?? ?都能调用一般属性 和 一般方法
?? ?可以放置在类成员的任意位置(属性 方法 构造 块)
? ? ? ? ? 注意调用一般方法的时候可以来回互相调用(写法 编译好用) 执行可能产生问题(StackOverflowError)
?? ?可以调用构造方法(放在构造方法的第一行)
? ? ? ? ? this和super在构造方法中调用另一个类的构造方法不能同时出现在第一行(super会默认出现在子类构造方法的每一行
? ? ? ? ?随便调用一个子类的构造方法时,都会有一个父类的构造方法被先调用出来)
?? ?如果第一行调用其他的构造方法时,就会被占用)
? ? ? ? ? 构造方法之间不能来回互相调用(编译就不好用) ?
? ? ? ? ? 当子类调用构造方法时,会默认先调用父类的构造方法
1. 概念:一个类中的一组方法 ?相同的方法名字 ?不同的参数列表 ? 这样的一组方法构成了方法重载
? ??? ??? ?参数列表的不同体现在哪里?
? ??? ??? ?参数的个数 ? 参数的类型 ? 参数的顺序
2. 作用:为了让使用者便于记忆与调用 ? 只需要记录一个名字 ?执行不同的操作 ?
3. 自己也可以设计方法重载
? ??? ??? ?调用方法的时候 ?首先通过方法名字定位方法
? ??? ??? ?如果方法名字有一致 ?可以通过参数的数据类型定位方法
? ??? ??? ?如果没有与传递参数类型一致的方法 ?可以找一个参数类型可以进行转化(自动)
4. JDK1.5版本之后 出现了一个新的写法
? ??? ??? ?int... x?? ?动态参数列表?? ?类型固定?? ?个数可以动态 0--n都可以
? ??? ??? ?x本质上就是一个数组 ?有length属性 ?有[index]
? ??? ??? ?动态参数列表的方法 ? 不能 ?与相同意义的数组类型的方法构成方法重载 ?本质是一样的
? ??? ??? ?动态参数列表的方法 可以不传参数 相当于0个 数组的方法 必须传递参数
? ??? ??? ?动态参数列表在方法的参数中只能存在一份儿 ?且必须放置在方法参数的末尾
is-a?? ??? ?继承 ? 实现
?? ??? ?继承通过extends关键字 (单继承)
?? ??? ?实现通过implements关键字 (多实现 接口)
?? ??? ?注意方法重写 ?方法重载区别 ? ?注意Object类及方法 ? 注意内存结构
has-a?? ??? ?组合 ? 聚合 ? 关联 ?(一来就有)
?? ??? ?一个类的对象放置在另一个类中作为属性
use-a(need-a)?? ?依赖 ?(后天组合在一起)
?? ??? ?一个类的方法中使用到了另外一个类的对象 ? ?方法内部new ?方法传递参数
类关系的设计: 高内聚 低耦合 ? ? ?继承(实现) > 组合 > 聚合 > 关联 > 依赖
public | 公共的 | 本类 | 同包 | 子类 | 当前项目中任意类的位置只要有对象都可以访问 |
protected | 保护的 | 本类 | 同包 | 子类 | 通过子类对象调用父类里面的protected方法,在子类范围内 子类对象可以自己访问,不在同一包中时调用父类自己的protected调用不到 |
默认不写 | 默认的 | 本类 | 同包 | ||
private | 私有的 | 本类 |
最终的 不可更改的
修饰属性 ?修饰一般方法 ?*修饰块 ?修饰类(内部类)
特点:
静态元素在类加载时就初始化啦,创建的非常早,此时没有创建对象
静态元素存储在静态元素区中,每一个类有一个自己的区域,与别的类不冲突
静态元素只加载一次(只有一份),全部类对象及类本身共享
由于静态元素区加载的时候,有可能没有创建对象,可以通过类名字.的形式直接访问
可以理解为静态元素不属于任何一个对象,属于类的
静态元素区Garbage Collection(垃圾回收器)无法管理,可以粗暴的认为常驻内存
非静态成员(堆内存对象里)中可以访问静态成员(静态区)
静态成员中可以访问静态成员(都存在静态区)
静态成员中不可以访问非静态成员(个数 一个出发访问一堆相同名字的东西 说不清)(静态元素属 于类,在静态元素区 非静态成员属于对象自己)
静态元素中不可以出现this或super关键字(静态元素属于类)
静态常量 全部字母大写 用_分隔 BOOKSTORE_ADMIN
静态常量的应用场景
增强程序的可读性 static final 属性=0
抽象的---(很不具体 没有具体的执行 只是个概念,没有执行体)
??? ?1. 可以修饰什么
? ? ? ? ? ? ? ? ? ? 不能修饰属性 属性是一个变量空间(容器) 抽象不了
? ? ??? ?修饰方法?? ?用abstract修饰符修饰的方法 ?只有方法的结构 没有方法执行体叫做抽象方法
? ? ??? ?当然注意native修饰的方法虽然也没有方法体 但是不是抽象方法 只是执行的过程是其他语言写的 看不见
? ? ??? ?修饰类
? ? ??? ?用abstract修饰符修饰的类 叫做抽象类
??? ?2. 修饰后有什么特点
? ? ??? ??? ?抽象类中必须有抽象方法么? ?不是必须含有抽象方法 ?
? ? ??? ??? ?抽象方法必须放在抽象类中么? ?目前来看必须放在抽象类中(或接口中) ?普通类是不允许含有抽象方法
??? ?3. 研究一下什么叫抽象类 ?抽象类有什么特点?(通常用来描述事物 还不是很具体)
? ? ??? ?1. 类里面有什么 ?成员
? ? ? ? ??? ??? ?属性?? ?可以含有一般的属性 ?也可以含有 private static final等等(跟普通类的属性一样)
? ? ? ? ??? ??? ?方法?? ?可以含有一般的方法 ?也可以含有 private static final等等(跟普通类里面的方法使用一样)
? ? ? ? ??? ??? ??? ? ? 注意:抽象类中是允许含有抽象方法(只有方法结构 没有方法执行体)
? ? ? ? ??? ??? ?块?? ?可以含有一般的程序块 也可以含有static程序块
? ? ? ? ??? ??? ?构造方法?? ?可以含有构造方法 ?包括重载 ?抽象类不能通过构造方法创建对象
? ? ??? ?2. 类如何使用 ?创建对象
? ? ? ? ??? ??? ??? ?抽象类含有构造方法 ?但是我们不能通过调用构造方法直接创建对象
? ? ? ? ??? ??? ??? ?抽象类只能通过子类单继承来做事
? ? ? ? ??? ??? ??? ?为什么不让我们调用构造方法创建对象?因为抽象方法是一种概念(残次品)
? ? ? ? ??? ??? ??? ?为什么还有呢?必须通过子类继承来实现,子类会间接调用父类的构造方法如果没有就调用不到
? ? ??? ?3. 类和类的关系
? ? ? ? ??? ??? ??? ?抽象类----直接单继承----抽象类?? ? 可以
? ? ? ? ??? ??? ??? ?抽象类----直接单继承----具体类 ?可以 ?(用法通常不会出现)
? ? ? ? ??? ??? ??? ?具体类----直接单继承----抽象类 ?不可以 ?(将父类的抽象方法具体化 ?或子类也变成抽象类)
? ? ??? ?4. 小问题
? ? ? ? ??? ??? ?抽象类中能不能没有抽象方法 ?全部都是具体成员 ?可以
? ? ? ? ??? ??? ?抽象类中能不能没有具体成员 ?全部都是抽象方法 ?可以 ---> 抽象类抽象到极致 质的变化 ---> 接口
? ? ? ? ??? ??? ?接口可以理解为是抽象类抽象到极致--->还是一个类的结构 ? 不能用class修饰 改用interface修饰
什么是接口(通常是为了定义规则) ?如果一个类实现了接口就必须把接口里面的方法具体化
接口也是一个类的结构 ?只不过 用interface修饰 替换原有的class
只定义规则 ?不描述具体过程
有什么成员 属性 不能含有一般属性 只能含有公有的静态的常量 public static final (这三个修饰符都是可以默认不写的,写与不写都是代表这三个) 方法 不能含有一般方法 只能含有公有的抽象的方法(1.8 defualt修饰具体方法) 块 不能含有一般程序块 也不能含有static块(块本身就是具体的 接口中不让有具体的) 构造方法 不能含有构造方法 接口没有构造方法,不能创建对象,只能通过子类多实现(implements)来做事
如何使用 创建对象 不能创建对象 只能通过子类多实现(implements)来做事 public class A implements B,C,D{ }
与别的类结构关系 接口不能继承别的类 最抽象 抽象类----直接多实现----接口 可以 具体类----直接多实现----接口 不可以(必须将接口中抽象的方法具体化(重写)或自己变成抽象类) *接口---多继承---接口 可以直接多实现
?? ?接口通常定义规则 ? ? 抽象类用来描述事物 ? ? 类用来具体描述细节
1. 加载父类
2. 父类会产生自己的静态空间 ? 属性 方法 块
? ? ? ? ? ? ? ? ?执行静态块
3. ?加载子类
4. 子类会产生自己的静态空间 ? 属性 方法 块
? ? ? ? ?执行静态块
5. ?开辟对象空间
6. 加载父类的非静态成员 ? 属性 方法 块 构造方法
7. 执行块 ?执行父类构造方法
? ?加载子类的非静态成员 ? 属性 方法 块 构造方法
8. 执行块 ?执行子类构造方法
9. 将对象空间的地址引用交给 变量来存储
创建对象在堆内存
方法在栈内存临时执行,用完即被回收
在创建对象前会先在方法区加载一个类模板
引用数据类型赋值时是看堆内存中的地址
堆内存中的元素在没有指定时都是有默认元素的
new一个东西就会在堆内存开辟一个空间
执行main时会在栈内存开辟一个空间
执行main里面调用方法? 又会在栈内存开辟一个空间执行
同一个对象体现出来的多种不同形态(身份) 将一种行为表现出不同的效果要想实现多态的效果 需要现有继承关系 使用多态的前提是需要有继承关系。
体现:
1. 父类类型的引用 ?指向 ?子类的对象 ? ?
? ?Person p = new Teacher();//做了一个自动的向上转型
? 调用的属性执行的时Person(父类)中的属性?
? ?当调用的一个方法如果Teacher里面有这个方法时就执行Teacher里面的方法 ? 如果Teacher里面
? ? ? 没有这个方法就从Teacher一层一层往上找,最先在哪里找到就执行哪里的 ?可以执行Person独有的方法
2. .该引用只能调用父类中定义的属性或方法?? ?
3. 如果子类中将父类的方法重写,那么调取方法后执行的结果是子类重写之后的那个结果
? ??? ??? ??? ?如果父类与子类有同名的属性 ??? ??? ?执行父类的属性(属性没有重写这一说法)
? ??? ??? ??? ?如果父类与子类有同名的方法(重载)?? ?执行子类重写之后的方法
4. 若想要调用子类中独有的成员
? ??? ??? ??? ?(强制类型转化) ?造型 铸型 ?(向上/向下转型)
? ? ? ? ? ? ? ?Teacher t=(Teacher)p;//向下转型需要强制转换
? ? ? ? ? ? ? ?调用属性时执行的是Teacher的属性 如果调用的方法如果没有在Teacher中就看继承关系
5. 造型时(强制向下转型时) 若需要转换的类型与真实对象的类型不匹配 会产生一个
? ??? ??? ?运行时异常ClassCastException
? ??? ??? ??? ?ClassCastException ? 造型 ?铸型 异常
? ??? ??? ??? ?如果想要避免造型的异常 ?可以用instanceof关键字来进行判断
? ??? ??? ??? ?对象 ?instanceof ?类 ?(p instanceof Teacher)比较前面对象和后面类型是否匹配
指的是在Java中可以将一个类定义在另一个类的内部。内部类可以定义在 类的内部 (与类成员层次
一致) 内部类可以定义在 方法/块内部 (与类成员相差一个层次 方法的局部变量一个层次)。
成员内部类 将一个类直接定义在类的里面,作为成员,与属性或方法层次一致
成员内部类可以与正常类一样 使用不同的修饰符来修饰
好处1.省略了一个.java文件 好处2.成员内部类中可以访问外部类的所有成员 包括私有的
若想要在内部类中通过对象.调用外部类成员 外部类.this.外部类成员;
内部类存在后 源代码进行编译 产生一个字节码 Demo$InnerDemo.class 如果想要使用内部类的属性和方法 必须创建对象 通过外部类对象操作
Demo d=new Demo();
Demo.InnerDemo id=d.new InnerDemo();
局部内部类 将一个类定义在方法/块里面,作为成员的内部结构,与临时的局部变量一个层次 局部内部类像是一个局部的变量一样,不能用public protected private及static
只能用abstract或final
局部内部类命名规则Demo$1InnerTestMethod Demo$2InnerTestMethod
局部内部类使用的变量只能是final修饰
局部内部类可以访问外部类成员 局部内部类也能访问局部变量要求局部的变量必须是final
匿名内部类 成员匿名内部类 局部匿名内部类?
通常接口或抽象类的具体子类这样写,当然具体的类也可以有匿名子类
开发中为了省略一个类文件 上述写法比较常见
匿名内部类很特殊 只有类体 没有类的所有结构( 修饰符 名字 继承 实现)
不能用任何修饰符来修饰 匿名内部类也没有构造方法
public interfase Test{
public void test();
}
public class TestMain{
public static void main(String[] args){
Test t = new Test(){
public void test(){
}
};
}
}
静态内部类 成员静态内部类 不需要外部类对象,通过正常的方式直接创建内部类 静态元素不能访问非静态成员(自己类和外部类)
运行时异常(非检查异常)
InputMisMatchException 输入类型不匹配
input.nextInt();? 输入一个整数a
ArrayIndexOutOfBoundsException 数组索引越界
静态初始化? int[] array = {10,20};
array[2]? 索引超出边界
NegativeArraySizeException 创建数组时候长度给了负数 数组的长度不合法
?动态初始化? int[] array = new int[-2];
NullPointerException
?引用为null可以?? 还拿来使用就不行啦
int[][] array = new int[3][];
array[0][0] = 10; //空元素再拿来用
int[] array = null;
array[0] = 10;//空元素再拿来用
Person p=null;//可以为空
p.toString();//为空还拿来用就会出现异常
NumberFormatException
数字格式化异常—将字符串转化为数字发现字符串里面不是数字
Integer.parseInt(“a”)
ArithmeticException
数学异常 ??整数/0??
(小数可以除0)//除以0结果为infinity(无穷)
ClassCastException??
造型? 铸型 异常
造型时(强制向下转型时) 可能会出现一个运行时异常
将对象类型还原时 与真实类型不匹配
illegalArgumentException??? 非法参数异常
ArrayList? list = new ArrayList(-1);//长度给负数
Random r = new Random();
r.nextInt(int bound);?? 随机产生一个? [0--bound)? 整数?
注意bound必须为正数? 否则会出现异常
StringIndexOutOfBoundsException 字符串越界
String str = "abc";
str.charAt(5);
IndexOutOfBoundsException 集合越界
List家族
ArrayList? list = new ArrayList();
list.add(); list.add(); list.add();
list.get(5);
StackOverflowError 栈溢出错误 ??方法来回调用
原因:构造方法之间来回的调用(每次调用都会产生一个新空间,原来的空间还没有执行完毕)
OutOfMemoryError
堆内存溢出错误