黑马视频(7/1)
Java SE
day01 计算机基础知识
- JDK 全称 Java Development Kit
- JRE 全称 JAVA RunTime Environment
- java的运行依靠 JVM 全称 Java Virtual Machine
- java 程序运行:源文件( .java ) -->编译器( compiler ) -->字节码文件( .class ) --> 解释器运行字节码文件
- java 之父 詹姆斯·高斯林( james Gosling ) ,Oak --> java,IBM --> Sun
- write once , run anywhere
jdk 下的几个文件
- bin: 可执行程序
- db: 小型数据库,javaDB,纯java编写
- include : 存放的头文件
windows 下几个经常使用的快捷键
- Tab 制表符
- Shift 上当转换键
- Ctrl 控制键
- Alt “ Alter ” 的缩写,汉语 “ 改变 ”
- PrScrn ( PrintScreen )摁下之后没反应,之后打开画图,Ctrl + V ,就可以捕获刚才的截图。
- win+ D 快速显示桌面
- win+ R 执行 运行 命令
- win + L 切换用户
- win + E 打开我的电脑
- 学习一门语言的第一步就是用这门语言书写出 HelloWord .
- 注释会增加代码的可读性,所以要经常加注释
- 输出十进制,直接输出即可;输出整数,二进制,需要以数字0B开头;输出整数,八进制,以数字0开头,输出整数,十六进制,以数组开头 OX(0-9 A-F),只要有点都是浮点类型的数;字符常量,单引号包裹,只能写一个字符;字符串,双引号包裹。
day02 进制运算、数据类型等
计算机设备中存数数据是 0 和 1 ,又被称为 bit ( 位 ) ,是最小信息单元 ,一般用小写字母 b 表示 。 8个比特位表示一个字节 ( byte ),是计算中的最小存储单元。程序运行时,分配给程序的是一个字节而不是一个位。
- 一个字节 通常被称为 1B ,
- 1024B 通常被称为 1KB ,
- 1204KB 通常被称为 1MB ,
- 1024MB 通常被称为 1GB ,
- 1024GB 通常被称为 1TB
- 1024TB 通常称为 1PB
- 对于买的硬盘或者U盘内存的计算
500G = 50010001000*1000 / 1024 /1024/1024 约等于 465 G - 十六进制 4个二进制一组,八进制 3个二进制一组
任意进制转十进制:系数*基数的权次幂相加
- 系数:每一位上的数据
- 基数:x进制,基数就是x
- 权:在右边,从0开始编号,对应位上的编号就是该权位。
8421码 快速转换法,都要先换位2进制才能用
- 1 1 1 1 1 1 1 1
- 128 64 32 16 8 4 2 1
- 11001100 = 4+8+68+128 = 204
- 十进制转8进制: 111 = 7 100 = 4 ,7就是八进制中最大的数,结果:74
- 十进制转十六进制:0011 = 3 1100 = C ,结果:3C
- 十进制用快速转换法转变为2进制:60和128、64比较,没128大,所以第一位0,64比较,第二位也是0,和32比较,减去剩下28,第三位是1,和16比较,能减去,剩下12,所以第四位1,以此类推,第五位1,第六位1,剩下第7位,第8位也是0,所以结果:00111100
原码
- 二进制定点表示法,最高位符号位,0表示正,1表示负,其余表示数值大小
- -7和7的二进制表示:
- +7 = 0 0000111 反码: 0 0000111 补码: 0 0000111
- -7 = 1 0000111 反码: 1 1111000 补码:1 1111001
- 反码 :正数的反码与原码相同,负数的反码是对其原码逐位取反,符号位除外。
- 补码:数的补码与其原码相同,负数的补码是在其反码的末位加1,求反码在补码的最后一位减一
- java 中进行运算的时候都是以补码进行运算的。
day03 运算符
- char可以存储汉字是因为使用的是 Unicode 编码,占两个字节,中文刚好也占两个字节,单引号放单个字符。
- 任何一个正整数 % 2 不是 0 就是 1 可以当做一个判断条件
byte b = 10 ;
b ++ ; // b = (byte) (b+1)
b = b + 1 ; // b = b + 1 结果是 int 类型 , 强制转为 byte 类型,会出现精度损失
short s = 1;
s+=1 ; // s = (short)(s+1) ;
- 改变两个变量的值,不需要第三方变量(有弊端,可能超过取值范围 ):
int x = 5, y = 10 ;
x = x + y ;
y = x -y ;
x = x -y ;
--------------
// 利用异或操作符运算
// 一个数据对另一个数据异或两次,本身不变
x = x ^ y ;
y = x ^ y ;
x = x ^ y ;
- 关于左移。向左移动几次,就是乘以 2 的 几次幂。
- 关于右移,向右移动几次,就是除以 2 的几次幂
- 最有效率的 2 * 8
System.out.println(2 << 3) ;0
day04 循环结构
- 有小括号不能有分号,有分号不能有小括号
- do...while() 至少执行一次循环,while()、for() 必须先判断,成立了再继续执行语句。
- return :结束方法,break:跳出循环,continue:终止本次循环继续执行下次循环。
- switch语句中,表达式的数据类型,可以是byte,short,int,char,enum(枚举),JDK7后可以接收字符串。
day05 数组
* [I@19bb25a
- [ 代表一个数组,几个 [ 就是几维数组
- I 代表 int 类型
- @ 是固定的
- 19bb25a 代表的是十六进制的地址值
- 栈(FILO): 存储局部变量。局部变量:定义在方法声明上和方法中的变量
- 堆:存储 new 出来的数组或者对象
- 方法区: 相当于代码仓库,字节码文件加载到内存中,就是进入到了方法区中
- 本地方法区:和系统相关
- 寄存器:给 cpu 使用
- 数组初始化不允许动静结合
int[] arr1 = new int[2] ; // 动态初始化
int[] arr = new int[5]{1,2,3,4,5} ; //不允许这样写,属于动静结合
int[] arr2 = {1,2,3,4,5} ; //静态初始化
int[] arr3 ;
arr3 = new int[]{1,2,3,4,5}; //静态初始化
- 访问数组中不存在的索引,会出现索引越界异常。
方法:
- arr.length -->表示数组长度 ,取值的最大长度是 arr.length -1 (比如 arr.length 是5,那么可取的最大长度就是4)
二维数组的定义:
- 数据类型 数组名 [] [] =new 数据类型m ;
- 数据类型 [] 数组名[] = new 数据类型m ; 例如: int[] y[]
- int[] x,y[] ; x是一维数组,y是二维数组
- 基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失。
- 引用数据类性的值传递改变原值(例如:数组),因为即使方法弹栈,但是堆内存数组对象还在,可以通过地址继续访问。
- Java 中只有传值,因为地址也是值,这是Java之父所认可的。
day06 面向对象 基础
java 中类是最基本的单位。
- 成员变量: 就是事物的属性
- 成员方法:就是事物的行为
- 类是对某一类事物的抽象描述,而对象用于表示现实中该类事物的个体。
- 创建一个对象后,如果没有任何引用指向该对象,那么该对象就会变成垃圾,被垃圾回收机制回收。
- 创建对象后实际上是把地址值赋给那个类型的那个变量。
- 当这个对象使用完后,main 方法也弹出栈,所有的引用都将置为空。
成员变量:
- 在类中方法外
- 在堆内存(成员变量属于对象,对象进入堆内存)
- 随着对象的创建而存在,随着对象的消失而消失
- 有默认初始值 0 、 null 、 false
局部变量:
- 在方法定义中或者方法声明上
- 在栈内存(局部变量属于方法,方法进入栈内存)
- 随着方法的调用而存在,随着方法的调用完毕而消失
- 没有默认初始值,必须定义,赋值,然后才能使用
- 局部变量的名称可以和成员变量的名称一样,但是在方法中使用的时候,采用的是就近原则。
- 基本数据类型变量包括:byte,short,int,long,float,double,boolean,char
- 引用数据类型包括:数组,类,接口,枚举,
- 引用数据类型当参数,给的是地址值。基本数据类型当参数,给的是值
- 匿名对象只适合对方法的一次调用,因为多次调用就会产生多个对象。
- 匿名对象可以调用属性,但是没有意义,因为调用后就变成了垃圾。如果需要赋值。还是要创建有名字的对象。
- 跟主函数在一起的方法都加静态。
- 匿名对象可以当做参数传递。实际是把地址值传了过去。
- 封装:指隐藏对象的属性和实现细节,,仅对外提供公共访问方式。把不需要对外提供的内容都隐藏起来,把属性隐藏,提供公共方法对其访问,
- this 关键字代表当前对象的引用,用来区分局部变量和成员变量。对象中记录了什么地址,this 中就记录了什么地址。成员变量必须由对象来调用。
- get 方法中返回的变量,系统会自动加上 this 关键字。
day07 面向对象 构造方法等
构造方法:给对象的数据(属性)进行初始化:
- 方法名与类名相同(大小写也要一样)
- 没有返回类型
- 没有具体的返回值
- 如果没有给出构造方法,系统将自动提供一个默认的无参构造方法。
- 如果给出了构造方法,系统将不提供默认的构造方法,这个时候如果还想用无参构造方法,必须自己给出,建议永远给自己无参构造方法。
- 构造方法主要是给属性进行初始化,set 方法主要是修改属性值。
创建一个对象并调用的步骤:
- xxx.class 加载进内存,
- 声明一个 xxx 类型的引用,
- 在堆内存创建对象
- 给堆对象中属性默认初始化值
- 属性进行显示初始化
- 构造方法进栈,对对象中的属性进行赋值,构造方法弹栈
- 将对象的地址赋值给引用
static 关键字特点:
*随着类的加载而加载- 优先于对象存在
- 被类的所有对象所共享(如果某个成员变量是被所有对象所共享的,那么他应该定义为静态)(共性用静态,特性用费静态)
- 可以通过类名调用
- 他本身也可以通过对象名调用
- 但是推荐使用类名调用,可以不创建对象,少占用内存
- 静态修饰的内容一般称为:与类相关的类成员,类变量
static 注意事项 :
- 在静态方法中没有 this 关键字,静态是随着类加载而加载的,this 是随着对象的创建而存在,静态比对象先存在
- 静态方法:只能访问静态的成员变量和静态的成员方法
- 非静态方法:可以访问静态或者非静态的成员变量,可以访问静态或者非静态的成员方法
- 即:静态只能访问静态
- 静态变量也叫类变量,成员变量也叫对象变量
- 静态变量属于类,成员变量属于对象,所以也被称为实例变量或者对象变量
- 静态变量存储于方法区的静态区,成员变量存储于堆内存,
- 静态变量随着类加载和消失,成员变量随着对象得创建与消失
- 静态变量可以通过类名调用,也可以通过对象调用,成员变量只能通过对象调用。
- public :被 JVM 调用,所以权限要足够大
static : 被 JVM 调用,不需要创建对象,直接类名.对象即可调用
void:被 JVM 调用,不需要有人和的返回值
main:这样写才可以被 JVM 识别,但是不是关键字
String[] agrs :以前是用来接收键盘录入的,可以修改。现在也不用了,Scanner 可以代替 - 如果一个类中所有的方法都是静态的,需要再多做一步,创建私有构造方法。目的是不让其他类来创建对象调用静态方法。
文档注释:需要在 / xxxx */ 中书写 javadoc -d api -version -author xxx.java
- @author 作者
- @version v1.0 版本
- @param arr 方法说明
- @return 对返回值类型的描述
Math.Random() 生成随机的大于等于0.0 小于1.0的伪随机数
- 生成1-100随机数
- Math.random() 0.0000 - 0.9999
- Math.random() *100 ===> 0.000-99.999
- (int) ( Math.Random() * 100 ) ==> 0 - 99
- (int) ( Math.Random() * 100 ) + 1 ==> 1 - 99
day08 面向对象 代码块的分类
- 局部代码块 : 在方法中出现,限定变量生命周期,及早释放,提高内存利用率
- 构造代码块,在类中方法外出现,多个构造方法中相同的代码存放到一起,每次调用构造都执行,在构造方法前执行,每创建一次对象就会执行一次,优先于构造函数执行
静态代码块:
- 在类中方法外出现,加了 static 修饰符
- 在类中方法外出现,加上static 修饰符,用于给类进行初始化,在类加载的时候就执行,并且只执行一次
- 一般用于加载驱动
- 主方法中的静态代码块 优先于主方法执行
关于继承:
- java 中只支持单继承,不支持多继承
- java 支持多继承(继承体系)
- 如果想用这个体系的所有功能用最底层的类创建对象(子类可以使用父类,父类不能够使用子类)
- 如果想用这个体系的共性功能,看最顶层的类
- 子类只能继承父类的所有非私有的成员(成员方法和成员变量)
- 子类不能继承父类的构造方法,但是可以通过 super 关键字访问父类的构造方法
- 不要为了部分功能而去使用继承
- 字父类出现同名变量,使用就近原则,使用子类中的值。但是开发中不会出现这种情况,因为子类继承父类就是为了使用父类的成员,如果定义了同名的就没有意义了。
this 与 super
this:
- 代表当前对象的引用,谁来调用我,我就代表谁
- this.成员变量 调用本类的成员变量,也可以调用父类的成员变量
- this(....) :调用本类的构造方法
- this.成员方法 调用本类的成员方法,也可以调用父类的成员方法
super :
- 代表当前对象父类的引用
- super.成员变量,调用父类的成员变量
- suoer(....) 调用父类的构造方法
- super.成员方法 调用父类的成员方法
子类中的构造方法,默认都会访问父类中的空参构造方法
- 因为子类会继承父类中的数据,可能还会使用父类的数据,所以子类初始化之前,一定要先完成父类数据的初始化
- 每个构造方法的第一条语句默认都是:super() Object类最顶层的父类,用来访问父类中的空参构造方法。
- 如果父类没有无参构造方法,子类可以通过super或者 this 解决, super(...) this(...) 必须出现在构造方法的第一条语句上
- 子类方法和父类方法相同,还有一个名字叫做:重写,复写,覆盖,返回值类型可以使子类或者父类。
- 当子类需要父类的功能,而功能主题子类有自己的内容时,可以重写父类中的方法,这样既继承了父类的功能,又定义了子类特有的功能。
- 父类中的私有方法不能被重写,因为私有方法不会被继承,子类重写父类方法的时候,访问权限不能更低,最好一致
- 父类静态方法子类必须通过静态方法进行重写,定义子类的目的是为了比父类更加强大 ,静态只能覆盖静态,算不上重写
- 子类重写父类方法的时候,最好声明一模一样。
overload 和 override :
- overload 可以改变返回值类型,只看参数列表
- 方法重写:子类中出现了和父类中方法声明一模一样的方法,与返回值类型欧冠,返回值一致(或者是子类或者是父类)的
- 方法重载:本类中出现的方法名一样,参数列表不同的方法,与返回值类型无关,
- 子类对象调用方法的时候,先找子类本身,再找父类。
- 子类调用父类中的方法就是加 this 或者 super 。
final :
- 修饰类,类不能被继承
- 修饰变量,变量就成了常量,只能够被赋值一次
- 修饰方法,方法不能被重写
- 一般和 public static 共用
- 修饰基本类型:值不能被改变
- 修饰引用类型,是地址值不能被改变,对象中的属性可以改变。
- 初始化时机:显示初始化、在对象构造完毕前初始化即可。成员变量的默认初始化值是无效值
- 常量命名:如果是一个单词,所有字母都大写,如果多个字母,每个单词字母都大写,每个单词用下划线隔开
day09 面向对象 多态
多态( polymorphic ) :
- 事物存在的多种状态,
- 前提是要有继承关系,要有方法重写,要有父类引用指向 子类对象
- 成员变量: 编译看左边( 父类 ) ,运行看左边(父类)
- 成员方法:编译看左边(父类),运行看右边(子类)
- 多态又叫动态绑定,编译看的是左边(父类)中有没有该方法,运行时看的是右边(子类),运行子类中的方法,真正进入栈内存的是子类的方法。
- 静态方法:编译看左边(父类),运行看左边(父类),(静态和类相关,算不上重写,所以访问还是左边的)
- 只有非静态的成员方法,编译看左边,运行看右边
- 基本数据类型自动类型提升和强制类型转换。
- 父类引用指向子类对象,就是向上转型,
多态好处:
- 提高了代码的维护性(继承保证)
- 提高了代码的扩展性(由多态保证)
- 可以当做形式参数,可以接收任意子类对象,
- 开发的时候很少在创建对象的时候用父类引用指向子类对象,直接创建子类对象更方便,可以使用子类中特有属性和行为
- 当做参数的时候多态最好,因为扩展性强
多态的弊端:
- 不嗯能够使用子类的特有属性和行为。
- 关键字 instanceof 用来判断前边的引用是否是后边的数据类型
抽象类:
- 抽象类和抽象方法必须使用 abstract 来修饰
- 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者接口
- 抽象类不允许被实例化的, 按照多态的方式,需要对其具体的子类实例化,才能使用
- 抽象类的子类要么是抽象类,要么重写抽象类中的所有抽象方法。
抽象类的成员特点:
- 成员变量:既可以是变量,也可以是常量,abstract 不能修饰成员变量
- 有构造方法,用于子类访问父类数据的初始化
- 成员方法:可以是抽象的也可以是非抽象的
- 抽象方法:强制要求子类做的事
- 非抽象方法:子类继承的事情,提高代码复用性
- 一个抽象类没有抽象方法,可以被定义为抽象类,这么做的目的只有一个,那就是不让其他类创建本类对象,交给子类完成。
- abstract 和 static 不能共存,被 abstract 修饰的方法没有方法体,被static 修饰 的可以用 类名. 调用 , 但是调用抽象方法是没有意义的。
- abstract 和 final 也不能共存。被 final 修饰的不让子类重写,被 abstract 修饰的 强制 子类重写,矛盾
- abstract 和 private 不能共存, 被 private 修饰的不让子类访问,被 abstract 修饰的 是为了让子类看到并强制重写,所以矛盾,
接口 interface
- 接口用关键字 interface 表示 : interface 接口名 { }
- 类实现接口用 implements 表示 class 类名 implenments 接口名 { }
- 接口不能实例化
- 接口中不能定义非抽象方法
- 接口的子类可以是抽象类也可以是具体类。推荐重写接口中的所有抽象方法。
- 成员变量只能是常量,并且只能是静态的公共的,
- 成员变量默认修饰符:public static final ,建议手动给出
- 构造方法:接口没有构造方法
- 成员方法:只能是抽象方法。默认修饰符 public abstract ,建议手动给出
- 类与类只能继承,只能单继承,可以多层继承
- 类与接口:可以单实现也可以多实现,可以在继承一个类的同时实现多个接口
- 接口与接口:继承关系,可以单继承也可以多继承
抽象类:
- 成员变量:可以是变量也可以是常量
- 构造方法:有
- 成员方法:可以抽象,也可以非重抽象
接口
- 成员方法:只能是抽象
- 成员变量:只能是常量
- 抽象类: 被继承体现的是 : is a 关系,抽象类中定义的是该继承体系的共性功能
- 接口: 被实现体现的是 like a 关系 , 接口中定义的是该继承体系的扩展功能
day10 面向对象,包,内部类
定义包的格式:
- package 包名
- 多级包用 . 隔开
- package 语句必须是程序的第一条可执行的代码
- package 语句在一个 java 文件中只能有一个
- 如果没有package 默认表示无包名
- javac -d . xxx.java
- import 导包, 代表通配符,用 导入可能导致查找慢,开发中一般具体导入需要的类
|条件|本类|同一个包下(子类和无关类)|不同包下(子类)|不同包下(无关类)|
|:--:|:--:|||||||
|private|Y|N|N|N|
|默认|Y|Y|N|N|
|protected|Y|Y|Y|N|
|public|Y|Y|Y|Y| - 面向对象(类及其组成所使用的常见修饰符)
A:修饰符:
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 抽象修饰符:abstract
B:类:
- 权限修饰符:默认修饰符,public
- 状态修饰符:final
- 抽象修饰符:abstract
- 用的最多的就是:public
C:成员变量:
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 用的最多的就是:private
D:构造方法:
- 权限修饰符:private,默认的,protected,public
- 用的最多的就是:public
E:成员方法:
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 抽象修饰符:abstract
- 用的最多的就是:public
F:除此以外的组合规则:
- 成员变量:public static final 接口
成员方法:
- public static
- public abstract
- public final
内部类访问特点:
- 内部类可以直接访问外部类的成员,包括私有。
- 外部类要访问内部类的成员,必须创建对象。
- 外部类名.内部类名 对象名 = 外部类对象.内部类对象; ( 两个new )
- 访问 静态内部类 : 外部类名.内部类名 对象名 = 外部类名.内部类对象 (一个ne
局部内部类访问局部变量必须用final修饰
- 当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用
匿名内部类:前提:存在一个类或者接口,类可以是具体类也可以是抽象类
- 本质:是一个继承了该类或者实现了该接口的子类匿名对象。
- 不能向下转型,因为没有子类类名,只有一个方法的时候使用
- new 类名或者接口名(){ //实现接口
重写方法; // 重写抽象方法
}; // 结束,整个代表的是一个对象
- 在开发中匿名内部类可以当做参数传递。本质是把匿名内部类看做一个对象 。父类引用指向子对象
- 链式编程:每次调用方法后还能继续调用方法,证明调用方法返回的是对象
day11 eclipse 使用和 Object 对象中方法
eclipse:
- 红色必须处理,黄色代表没使用
- F11 运行
- F4 打开父类
- Alt + / 提示符,内容辅助
- Ctrl + N 新建
- Ctrl + Shift + f 格式化
- Ctrl + Shift + o 整理包
- Ctrl + / 单行注释
- Ctrl +Shift + / 多行注释 , Ctrl +Shift + \ 取消多行注释
- Alt + 上下箭头 移动这一行
- F3 或者 Ctrl + 鼠标点击 --> 查看源码,选中类名
- Ctrl + Shift + t 查找具体类
- Ctrl + o 查找具体类的具体方法
- Ctrl + 1 给出建议,生成建议的代码
- Ctrl + D 删除 当前行或者选中的多行
- Alt + Shift + m 抽取方法
- Alt + Shift + r 改名
- Ctrl + Alt + 下 ,向下复制一行当前行
Alt + Shift + S
- o :生成有参构造
- c 生成空参构造
- r get set 方法
- s toString 方法
- jar 是多个 class 文件的压缩 ,主要是使用别人写好的东西,一般在 开发中都将用到的 jar 文件放在 lib 包中
Debug调试:
- 左键双击加上断点
- 进栈的地方就是加断点的地方
左上角:
- variables : 查看程序中的变量值的变化
- breakpoints:删除或者查看断点
- ForDemo 被查看的源文件
- Console 控制台
- API Application Programming interface 应用程序编程编程接口
Objext 类:是类层次结构的根类,每个类都使用Object作为超类,所有对象包括数组都实现这个类的方法,
- hashCode() ; native 修饰,代表借助本地资源计算出的 一个 hashCode 值,返回一个 int 数
- getClass() ,返回此对象的运行时类,获取该对象的字节码文件,
- getName() ,获取这个类的名称, 详细类名
- toString() , 返回该对象的字符串表示 getClass().getName + @ + Integer.toHexString(hashCode) , hashCode --> 换成了16进制返回 ,类名+@+hashCode 16进制表示方方式。没有实际意义,一般都选择将其进行重写。可以更方便的显示属性值。如果直接打印对象的引用,会默认调用toString方法
- Equals ,比较两个对象是否相等,比较的是两个对象的地址值,没有什么意义,开发中需要重写,因为开发中一般比较的对象的属性值,开发中认为相同属性的是一个对象
- == 和 euqals ,都可以作比较,返回的都是boolean ,
- == 是比较运算符,既可以比较基本数据类型,也可以比较引用数据类型,基本数据类型比较的是值,引用数据类型比较的是地址值
- equals 方法只能比较的是引用数据类型,equals 方法重写前,比较的是地址值,底层依赖的是 == , 但是比较地址值是么有意义的,所以需要重写 equals 方法,比较对象中的属性值,