基础知识掌握
JDK Java Development Kit java开发套件
文件名和类名要相同 文件名.java === public class 文件名{}
java是一个一个类构成的
main是java的入口
mac环境变量设置
- .zshrc
- .bash_profile
查看机器上所有java版本:
lijuncheng@lijunchengdeMBP ~ $ /usr/libexec/java_home -V Matching Java Virtual Machines (3): 11.0.4, x86_64: "Java SE 11.0.4" /Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home 9, x86_64: "Java SE 9" /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home 1.8.0_151, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home /Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home
src source的缩写
int 整数范围 -2^31~2^31-1 -2147483648~2147483647
标识符 Identifier
关键词 key word
二进制单位bit
Byte 硬盘存储单位 文件大小 1byte=8bit
整数:
- byte 1个byte
- short 2个byte
- int 4个byte
- long 8个byte
浮点数:
- float 4个byte
- double 8个byte
布尔类型,字符类型:
- boolean 1个byte
- char 2个byte
布尔运算符:
- ! 非
- & and
- && 当第一个条件为假之后,后面的条件就不执行了,它具有短路功能 & 两个条件都要执行 运算结果与&相同
- | 或
- || 运算结果与|相同
运算优先级:
- ()
- !
- * / %
- + -
- > >= < <=
- ==
- !=
- & && | ||
- =
进制:
- 0开头 8进制
- 0X开头 16进制
按位运算符:
- &
- |
- ^ 异或运算
- ~ 取反
位移运算符:
- >> 符号位不动
- >>> 符号位动
- << 符号位不动
掩码 mask 类似于 onehot
数值精度:
double>float>long>int>short>byte
字符集:字符的集合
- GBK常用汉字字符集合
- ASII码
- Unicode 全世界上所有常用字符 UTF-8、UTF-16
- java是使用UTF-16
char character字符
数字映射到字符 编码Encoding
Math.random(); 生成0到1之间的数字。
数组:
int[] book = new int[10]; 都是地址
多维数组:
double[][] scource = new double[2][3];
输入:
Scanner in = new Scanner(System.in);
a = i.next;
类
java 的精髓
// >> TODO 高亮注释 以程序本身内无关
实例 Instance
对象 Object
数组是一个特殊的类,每个数组对象占用的内存可以不一样。,这点和类的对象不同,类的对象一定相同。
NULL 引用类型的缺省值,代表为空。
NULL带来的问题NullPointerException NPE
数组的index也是一种地址引用 Eg:merchandise[7].name
成员变量一样,但是类名不一样,类就不一样。
包和访问修饰符
com.phone.ljc 类似于这样
- 包:层级关系 package 有package语句,则必须是类的第一行有效代码
- package的访问管理 import
Java只要不在同一个目录下就看不到,如果想看到就要路径加上类名,使用import语句。
public 访问修饰符、默认访问修饰符,只能被同一个包package里的类访问,不是一个包就不让访问。
包名package+类名=类的权限定名,同一个java中权限定名不重复,类名可以重复。
Method = Function
不可以用类调用方法,需要对象访问方法。
可以访问 局部变量 以及 成员变量
@see 和哪些类还有关系
@since 从jdk的什么版本开始有的
成熟的类,自己操作自己的成员变量。
成员变量是内部的状态。
1 Merchandise m1 = new Merchandise(); 2 m1.name = "旺仔小馒头!"; 3 m1.id = "32423432"; 4 5 m1.init("旺仔小馒头!", "32423432");
封装:自己管控、逻辑公用、避免重复
把类的数据和操作都放在一起
方法的签名:方法名+依次参数类型 返回值不属于方法签名、方法签名是一个方法在一个类中的唯一标识。
也就是:方法重载overload
重载的参数匹配规则,
double:int、double、short、byte
参数类型不完全匹配,会自动适配。
类型重载规则(不推荐这样使用):
- double float
- double long
构造方法(constructor):创建一个对象,自动实例化对象。 构造方法与类名一致,构造方法不能有返回值。
没有构造方法默认为一个无参的构造方法。构造方法只是能初始化成员变量。new 返回创建对象的引用。
构造方法重载:构造方法的不同逻辑,通过参数的类型个数区分开。必须是第一行,参数不能访问this自引用,不能访问成员变量。
浮点数除以0不会报错,整数除以0会报错。
构造方法用this指向引用变量。
<init> 构造方法、或者给成员变量赋值
静态变量:也叫做类变量。
Magic Number 贬义词、不要直接上数字0.95.
cost = cost * 0.95; ==》 cost = cost * discount;
static 不赋值,java也会给他一个初始值。静态变量命名:下划线 + 所有单词大写
静态变量就这一个,不会像成员变量一样,不用跟随对象的创建而创建,静态变量跟着类存在。
引用静态变量:
- import static om.gee.XXX
- 或者直接 类名.静态变量 在代码中使用
类 == 静态变量
静态方法:没有this自引用方法、类方法
静态方法的参数来自:方法自身的参数 和 静态变量(别的类或者自己类)
静态方法可以自己创建对象,或者通过参数调用,获得对象的引用,进而调用方法和访问成员变量。
方法也可以同import使用
静态方法的重载:成员方法重载一致
static代码块:给静态变量赋值,可以使用人任意类的静态变量。有先后顺序,定义在使用之前。
<clinit> 静态变量组织到这个方法中
访问修饰符:
- public 全局可见
- 缺省:当前包可见
- private:当前类可以见
成员变量、构造方法定义成private 可以自己修改
public方法类似于一种约定(契约),既然外面的代码可以使用,就意味着不能乱改,比如签名不能改之类的
Math 使用 static 将方法暴露处理啊,供调用。
string不可变,它是private的
StringBuild 用来凭借和处理字符串的类
继承不能访问父类的private成员
覆盖才是继承的精髓:签名和返回值一样的方法。
子类和分类沟通的桥梁 super,不可以使用super 访问分类的属性和方法,不可以使用子类成员变量和方法,可以使用静态方法。
调用父类的构造方法:
init()方法
40 多态
可以调用哪些方法,取决于引用类型,具体调用哪个方法,取决于实例所属的类是什么。
Java选择单继承的重要原因之一,在多继承的情况下,如果使用不当,多态可能会非常复杂,以至于使用的代价超过来了带来的好处。
多态:
- 静态多态:重载 overload
- 动态多态:覆盖 override
instanceof 操作符,可以片段一个指向的独享是否是某一个类型或者其子类是返回true,否则返回false
if(m instanceof Phone){
}
protected 对包和子类可见
final 不可以被集成,和修改
集成里的静态方法:
静态方法可以被继承
object没有成员变量,只有方法
重新更新java学习视屏笔记
1.类
Merchandise.java
1 // >> TODO 一个类以public class开头,public class代表这个类是公共类,类名必须和文件名相同。 2 // >> TODO public class后面紧跟类名,然后是一对打括号的类体 3 public class Merchandise { 4 // >> TODO 类体中可以定义描述这个类的属性的变量。我们称之为成员变量(member variable) 5 // >> TODO 每个成员变量的定义以;结束 6 String name; 7 String id; 8 int count; 9 double price; 10 11 } 12 13 // >> TODO 上面这整个类,其实就是创建了一个模版。描述了一种我们需要的数据类型。
2.类的 实例 Instance 与 对象 Object
类就是自己常见了一种新的数据类型,类也就是自定义类型。以一个java程序中不允许类同名
SuperMarket.java
1 public class SuperMarket { 2 public static void main(String[] args) { 3 4 // >> TODO 使用new操作符,可以创建一个类的实例/对象( instance/object )。 5 // >> TODO 使用new创建一个类的实例后,类中定义的每种变量都会被赋以其类型的初始值。 6 // TODO 这个和数组也是一样的 7 // >> TODO 使用一个同类型的对象变量,可以指向并操作这个实例。这两点和数组都很类似 8 // 创建一个Merchandise的实例,用m1指向它。 9 Merchandise m1 = new Merchandise(); 10 // 缺省值:每个对象的成员变量都会赋予成员变量的缺省值。 11 12 // 使用点操作符,给m1指向的实例赋值。 13 m1.name = "茉莉花茶包 20 包"; 14 m1.id = "000099518"; 15 m1.count = 1000; 16 m1.price = 99.9; 17 18 Merchandise m2 = new Merchandise(); 19 m2.name = "可口可乐 330ml"; 20 m2.id = "000099519"; 21 m2.count = 1000; 22 m2.price = 3.0; 23 24 25 // 卖出一个商品1 26 int m1ToSold = 1; 27 System.out.println("感谢购买" + m1ToSold + "个" + m1.name + "。商品单价为" 28 + m1.price + "。消费总价为" + m1.price * m1ToSold + "。"); 29 m1.count -= m1ToSold; 30 System.out.println(m1.id + "剩余的库存数量为" + m1.count); 31 32 // 卖出3个商品2 33 int m2ToSold = 3; 34 System.out.println("感谢购买" + m2ToSold + "个" + m2.name + "。商品单价为" 35 + m2.price + "。消费总价为" + m2.price * m2ToSold + "。"); 36 m2.count -= m2ToSold; 37 System.out.println(m2.id + "剩余的库存数量为" + m2.count); 38 39 40 // >> TODO 点操作符是用来访问/操作前面实体的属性的,类似于“的” 41 } 42 }
3.引用类型
引用:reference
引用 = 类型 + 实例
引用数据类型和基本数据类型本身都是一个地址。基本数据类型地址对应的值,就是变量的值。引用数据类型的值还是一个地址,通过“二级跳”找到实例。
ReferenceAndPrimaryDataType.java
1 public class ReferenceAndPrimaryDataType { 2 public static void main(String[] args) { 3 4 // >> TODO m1是一个Merchandise类型的引用,只能指向Merchandise类型的实例 5 // >> TODO 引用数据类型变量包含两部分信息:类型和实例。也就是说, 6 // TODO 每一个引用数据类型的变量(简称引用),都是指向某个类( class /自定义类型) 7 // TODO 的一个实例/对象(instance / object)。不同类型的引用在Java的世界里都是引用。 8 // >> TODO 引用的类型信息在创建时就已经确定,可以通过给引用赋值,让其指向不同的实例. 9 // 比如 m1 就是Merchandise类型,只能指向Merchandise的实例。 10 Merchandise m1; 11 m1 = new Merchandise(); 12 Merchandise m2 = new Merchandise(); 13 Merchandise m3 = new Merchandise(); 14 Merchandise m4 = new Merchandise(); 15 Merchandise m5 = new Merchandise(); 16 17 // >> TODO 给一个引用赋值,则两者的类型必须一样。m5可以给m1赋值,因为他们类型是一样的 18 m1 = m5; 19 20 System.out.println("m1=" + m1); 21 System.out.println("m2=" + m2); 22 System.out.println("m3=" + m3); 23 System.out.println("m4=" + m4); 24 System.out.println("m5=" + m5); 25 System.out.println(); 26 27 Merchandise m6 = m1; 28 System.out.println("m6=" + m6); 29 m6 = m5; 30 System.out.println("m6=" + m6); 31 System.out.println(); 32 33 34 System.out.println("m1=" + m1); 35 System.out.println("m2=" + m2); 36 System.out.println("m3=" + m3); 37 System.out.println("m4=" + m4); 38 System.out.println("m5=" + m5); 39 40 41 int a = 999; // 基本数据类型 42 43 } 44 }
结果:
m1=Merchandise@2503dbd3
m2=Merchandise@4b67cf4d
m3=Merchandise@7ea987ac
m4=Merchandise@12a3a380
m5=Merchandise@2503dbd3
m6=Merchandise@2503dbd3
m6=Merchandise@2503dbd3
m1=Merchandise@2503dbd3
m2=Merchandise@4b67cf4d
m3=Merchandise@7ea987ac
m4=Merchandise@12a3a380
m5=Merchandise@2503dbd3
引用数据类型,引用的是什么?
heap堆 实例存放的地方 、类似于公告板的地方 比如:string 也是引用类型
m1本身就是一个地址、所以才需要使用二级跳。
引用类型的大小:
- 64位jdk 64bit
- 32位jdk 32bit
堆内存、栈内存
类和对象的关系:
- 类是对象的模板,对象是类的一个实例
- 一个java程序中类名相同的类只能有一个,也就是类型不会重名
- 一个类可以有很多对象
- 一个对象只能根据一个类来创建
引用和类以及对象的关系:
- 引用必须是,只能是一个类的引用
- 引用只能指向其所属的类型的类的对象
- 相同类型的引用之间可以赋值
- 只能通过指向一个对象的引用,来操作一个对象,比如访问某个成员变量
数组
数组是一种特殊的类:
- 数组的类名就是类型带上中括号
- 同一类型的数组,每个数组对象的大小可以不一样,也就是每个数组对象占用的内存可以不一样,这点和类的对象不同。
- 可以用引用指向类型相同大小不同的数组,应为它们属于同一个类型
1 public class ArrayIsClass { 2 public static void main(String[] args) { 3 // >> TODO “数组变量”其背后真身就是引用。数组类型就是一种特殊的类。 4 // >> TODO 数组的大小不决定数组的类型,数组的类型是只是由元素类型决定的。 5 int[] intArr; 6 intArr = new int[1]; 7 intArr = new int[2]; 8 9 // 这个数组的元素就是二维的double数组,既double[][] 10 double[][][] double3DArray = new double[2][3][4]; 11 12 int[] a1 = new int[9]; 13 int[] a2 = new int[0]; 14 a2 = a1; 15 System.out.println("a2.length=" + a2.length); 16 double[] a3 = new double[5]; 17 // a3是double[]类型的引用,不可以用int[]类型的引用赋值。 18 double3DArray[1][2] = a3; 19 } 20 }
引用的数组
- 可以把类名当成自定义类型,定义引用的数组,甚至多维数组
1 public class RefArray { 2 3 public static void main(String[] args) { 4 Merchandise[] merchandises = new Merchandise[9]; 5 merchandises[0] = new Merchandise(); 6 merchandises[1] = new Merchandise(); 7 merchandises[0].name = "笔记本"; 8 System.out.println(merchandises[0].name); 9 10 System.out.println(merchandises[2]); 11 } 12 }
笔记本
null
缺省值
- null是引用类型的缺省值
- null代表空,不存在。可以读作空
- 引用类型的数组创建出来,初始值都为空。
- 带来NuLLPointerException(NPE)需要先判空在运行引用
- 直接输出null没有关系,但是引用的值输出则会报错。
1 public class CheckBeforeUse { 2 public static void main(String[] args) { 3 // 数组在创建出来之后,会按照类型给数组中的每个元素赋缺省值。 4 // 引用类型的缺省值是null 5 Merchandise[] merchandises = new Merchandise[9]; 6 // 给索引为偶数的引用赋值 7 for (int i = 0; i < merchandises.length; i++) { 8 if (i % 2 == 0) { 9 merchandises[i] = new Merchandise(); 10 } 11 } 12 13 // merchandises[7].name = "不存在的商品,不存在的名字"; 14 15 for (int i = 0; i < merchandises.length; i++) { 16 if (merchandises[i] != null) { 17 merchandises[i].name = "商品" + i; 18 } 19 } 20 21 for (int i = 0; i < merchandises.length; i++) { 22 if (merchandises[i] != null) { 23 System.out.println(merchandises[i].name); 24 } 25 } 26 } 27 }
5.自定义类
command / cutrl + 鼠标 点击会跳转类
引用类型可以随意组合
6.package管理
- 为了避免类在一起混乱,可以把类放在文件夹中。
- 不同包可以有相同名字的类
- 一个类只能有一个package语句,如果有package语句,则必须是类的第一行有效代码
- 其中.就是package
7.public
访问修饰符:
- 缺省访问修饰符,只能被同一个包package下面的文件访问。private
- public可以被任意包访问
类的全限定名 = 包名 + 类名 同一个java程序中权限定名不能重复
java就是使用类来描述世界,用类的实例让世界运转起来。
设置断点(breakpoint),debug调试运行程序。
8.方法
方法 Method Function 让类描述自己
1 package com.geekbang.supermarket; 2 3 public class MerchandiseV2 { 4 5 public String name; 6 public String id; 7 public int count; 8 public double soldPrice; 9 public double purchasePrice; 10 String madeIn; 11 12 // >> TODO 访问修饰符 13 // >> TODO 返回值类型:无需返回值则用void表示,void是Java中的关键字 14 // >> TODO 方法名:任意合法的标识符都可以 15 // >> TODO 参数列表:后续讲解 16 // >> TODO 方法体:方法的代码 17 // >> TODO 方法体内部定义的变量叫做局部变量 18 public void describe() { 19 double netIncome = soldPrice - purchasePrice; 20 System.out.println("商品名字叫做" + name + ",id是" + id + "。 商品售价是" + soldPrice 21 + "。商品进价是" + purchasePrice + "。商品库存量是" + count + 22 "。销售一个的毛利润是" + netIncome + "。制造地为" + madeIn); 23 } 24 }
方法可以使用的数据:对象的成员变量(member variable)
1 package com.geekbang.supermarket; 2 3 public class MerchandiseV2DescAppMain { 4 public static void main(String[] args) { 5 MerchandiseV2 merchandise = new MerchandiseV2(); 6 7 merchandise.name = "书桌"; 8 merchandise.soldPrice = 999.9; 9 merchandise.purchasePrice = 500; 10 merchandise.count = 40; 11 merchandise.id = "DESK9527"; 12 merchandise.madeIn = "China"; 13 14 merchandise.describe(); 15 } 16 }
方法返回值
1 package com.geekbang.supermarket; 2 3 public class MerchandiseV2 { 4 5 public String name; 6 public String id; 7 public int count; 8 public double soldPrice; 9 public double purchasePrice; 10 11 public void describe() { 12 System.out.println("商品名字叫做" + name + ",id是" + id + "。 商品售价是" + soldPrice 13 + "。商品进价是" + purchasePrice + "。商品库存量是" + count + 14 "。销售一个的毛利润是" + (soldPrice - purchasePrice)); 15 } 16 17 // >> TODO 在方法定义中指定方法的返回值类型 18 // >> TODO Java中一个方法只能有一种返回值,如果不需要返回值则用void表示 19 // >> TODO 如果定义了返回值,则必须使用 return 语句返回方法的返回值,return 是 Java 的关键字 20 // >> TODO 可以认为,返回值必须要能够用来给返回值类型的变量赋值 21 public double calculateProfit(){ 22 double profit = soldPrice - purchasePrice; 23 // >> TODO 这个return是代码块里的return,是return所在代码块的最后一个语句 24 if (profit <= 0) { 25 return 0; 26 } 27 // >> TODO return 语句必须是所在代码块的最后一个语句,否则就是语法错误 28 return profit; 29 30 // >> TODO 一个方法可以有多个返回语句。 31 } 32 33 // >> TODO 返回值如果是基本类型,则要类型完全相同,或者符合类型自动转换规则 34 public double getCurrentCount(){ 35 return count; 36 } 37 38 // >> TODO 如果不符合规则,可以使用强制类型转换 39 public int getIntSoldPrice(){ 40 return (int) soldPrice; 41 } 42 43 }
发生在代码块里的就留在代码块中,参数和方法的局部变量的数据就会被删除回收。
局部变量:
参数:
1 // >> TODO 方法的代码可以影响方法之外的数据。我们可以通过指向同一个对象的引用,操作这个对象里的属性 2 MerchandiseV2 paramRef = littleSuperMarket.merchandises[2]; 3 4 m.gift = giftBowl; 5 System.out.println("gift变换大法执行前"); 6 m.describe(); 7 paramRef.describe(); 8 m.changeToTheSameGift(paramRef); 9 System.out.println("gift变换大法执行后"); 10 paramRef.describe();
1 public void changeToTheSameGift(MerchandiseV2 m2) { 2 m2.gift = gift; 3 }
9.this指针
1 public void addCount(int count) { 2 // >> TODO 方法里隐藏着一个this自引用,指向调用这个方法的对象。 3 // >> TODO 使用一个对象调用方法,也叫做在这个对象上调用方法。因为方法可以访问这个对象的值。 4 // >> TODO 访问一个成员变量的完整形态,是"this.成员变量的名字" 5 this.count += count; 6 7 System.out.println("MerchandiseV2的addCount方法使用的对象是:" + this); 8 }
方法访问成员变量都是通过this自引用开始访问的
类通过成员变量和方法描述世界。
- 方法是java中代码执行的单元,是代码的载体,所有代码,都必须属于某一个方法。
- 方法是一串语句,加上数据输入this自引用和参数,执行后得到一个返回值,所以使用一个对象调用一个方法,可以叫做调用对象的方法,也可以叫做“在这个对象调用方法(invoke a method on an object)”
- 方法是类的一部分,不是对象的一部分。每个对象可以给成员变量赋不同的值,但是无法让方法有不同的行为,同理,无论在一个类中定义多少方法,都不会让影响创建一个对象所占用的内存
方法明确属于某一个类
类中的方法是没有前后关系的
10.类的成员变量让自己操作,不能让别的类来作
操作成员变量:
- 初始化成员变量
- 简单访问和设置成员变量的值(Java Bean) java豆子
- 专有的一些计算逻辑
- 用类定义成员变量,并把操作成员变量的代码都放在类里,就是封装
1 package com.geekbang; 2 3 import com.geekbang.supermarket.MerchandiseV2; 4 5 public class MerchandiseV2DescAppMain { 6 public static void main(String[] args) { 7 MerchandiseV2 merchandise = new MerchandiseV2(); 8 9 // merchandise.name = "书桌"; 10 // merchandise.soldPrice = 999.9; 11 // merchandise.purchasePrice = 500; 12 // merchandise.count = 40; 13 // merchandise.id = "DESK9527"; 14 15 // >> TODO 调用方法,完成对成员变量的操作 16 merchandise.init("书桌", "DESK9527", 40, 999.9, 500); 17 18 merchandise.describe(); 19 } 20 }
将内外分开
1 package com.geekbang.supermarket; 2 3 public class MerchandiseV2 { 4 5 public String name; 6 public String id; 7 public int count; 8 public double soldPrice; 9 public double purchasePrice; 10 11 public void init(String name, String id, int count, double soldPrice, double purchasePrice) { 12 this.name = name; 13 this.id = id; 14 this.count = count; 15 this.soldPrice = soldPrice; 16 this.purchasePrice = purchasePrice; 17 } 18 19 // >> TODO 定义方法 20 public void describe() { 21 System.out.println("商品名字叫做" + name + ",id是" + id + "。 商品售价是" + soldPrice 22 + "。商品进价是" + purchasePrice + "。商品库存量是" + count + 23 "。销售一个的毛利润是" + (soldPrice - purchasePrice)); 24 } 25 26 // >> TODO 定义方法 27 public double calculateProfit() { 28 double profit = soldPrice - purchasePrice; 29 // if(profit <= 0){ 30 // return 0; 31 // } 32 return profit; 33 } 34 35 public double buy(int count) { 36 if (this.count < count) { 37 return -1; 38 } 39 40 return this.count -= count; 41 } 42 }