文章目录
- 单例模式
-
- 饿汉三部曲(资源浪费)
- 懒汉三部曲(线程不安全)
- 异常-Exception
-
- 初步识别异常代码
- 解决方案-异常捕获( try-catch)
- Error and Exception
- 异常体系图
- 常见操作异常
-
- \1)NullPointerException 空指针异常
- \2)ArithmeticException 数学运算异常
- \3) ArrayIndexOutOfBoundsException 数组下标越界异常
- \4) ClassCastException 类型转换异常
- \5) NumberFormatException 异常的数字格式不正确
- 编译异常
-
- FileNotFoundException
- try-catch-finally
- try-catch-finally 总结执行顺序
- Integer类别:拆箱与装箱
-
- 转换包装和基本数据的原理
- 面试题
- 包装类型和 String 相互转换类型
- Integer 类面试题
- String 类
-
- String 理解和创建类别的对象
- 创建 String 对象的两种方式
- 两种创建 String 对象的区别
- 面试题
- String 常的常用方法
- StringBuffer 与 StringBuilder
-
-
- StringBuffer 类.基本介绍
- String VS StringBuffer
- String 和 StringBuffer 相互转换
- StringBuffer 类常见方法
- StringBuffer 类课堂测试题
- StringBuffer 类课堂测试题2
- StringBuilder 类.基本介绍
- StringBuilder 常用方法
- String、StringBuffer 和 StringBuilder 的比较
- String、StringBuffer 和 StringBuilder 的选择
-
- List | ArrayList | Vector
-
- List 接口及常用方法
-
- List 接口基本介绍
- List 常用的接口方法
- List 接口课堂练习
- List 三种通历方式 [ArrayList, LinkedList,Vector]
- 实现课堂练习 2
- ArrayList 底层结构及源代码分析
-
- ArrayList 的注意事项
- ArrayList 源代码分析(重点、难点).)
- Vector 底层结构及源代码分析
-
- Vector 的基本介绍
- Vector 和 ArrayList 的比较
- LinkedList 底层结构
-
- LinkedList 的全面说明
- LinkedList 底层操作机制
- LinkedList 增删案例
- ArrayList 和 LinkedList 比较
- HashSet 与 LinkedHashSet
-
- Set 接口及常用方法
-
- Set 基本介绍接口
- Set 接口的常用方法
- Set 接口的遍历
- Set 以界面常用方法为例
- Set 接口实现类-HashSet
-
- HashSet 的全面说明
- HashSet 案例说明
- HashSet 说明底层机制
- HashSet 课堂练习 1
- HashSet 课后练习 2
- Set 接口实现类-LinkedHashSet
-
- LinkedHashSet 的全面说明
- LinkedHashSet 课后练习题
- HashMap 与 HashTable(超重点)
-
- Map 接口及常用方法
-
- Map 接口实现类的特点 [很实用]
- Map 常用的接口方法
- Map 接口遍历法
- Map 接口课堂练习
- Map 接口实现类-HashMap
-
- HashMap 小结
- HashMap 底层机制及源代码分析
- HashMap 底层机制及源代码分析
- Map 接口实现类-Hashtable
-
- HashTable 的基本介绍
- Hashtable 和 HashMap 对比
- 总结-如何在开发中选择集合实现类(记住)
- 多线程详解
-
- 线程相关概念
-
- 程序(program)
- 进程
- 什么是线程
- 其它相关概念
- 基本使用线程
-
- 创建线程的两种方法
- 线程应用案例 1-继承 Thread 类
- 线程应用案例 2-实现 Runnable 接口
- 线程应用案例-多线程执行
- 如何理解线程?
- 继承 Thread vs 实现 Runnable 的区别
- 线程终止
-
- 基本说明
- 应用案例
- 常用的线程方法
-
- 第一组常用方法
- 注意事项和细节
- 应用案例
- 第二组常用方法
- 应用案例
- 课堂练习
- 用户线和守护线程
- 应用案例
- 线程的生命周期
-
- JDK 中用 Thread.State 枚举表示了线程的几种状态
- 线程状态转换图
- 写程序查看线程状态
- 线程的同步
-
- 先看一个问题
- Synchronized
-
- 线程同步机制
- 同步具体方法-Synchronized
- 分析同步原理
- 互斥锁
-
- 基本介绍
- 使用互斥锁来解决售票问题
- 注意事项和细节
- 线程的死锁
-
- 基本介绍
- 应用案例
- 应用案例
- 释放锁
-
- 下面操作会释放锁
- 下面操作不会释放锁
- 释放锁
-
- 下面操作会释放锁
- 下面操作不会释放锁
单例模式
饿汉式三部曲(资源浪费)
1.将构造器私有化(导致外部不可直接new你这个类的实例)
private GirlFriend(String name) {
this.name = name;
}
2.在类的内部直接创建(在自己的的类中创建一个属于自己的女朋友)
private static GirlFriend gf = new GirlFriend("红红");
3.提供一个static公共方法,返回gf对象(有static关键字是前提)
public static GirlFriend getInstance(){
return gf;
}
总代码(外部不可以new也不会创建多个对象,外部只可以通过这个类调用返回女朋友对象的这个方法获取)
public class single {
public static void main(String[] args) {
GirlFriend instance = GirlFriend.getInstance();
System.out.println(instance);
}
}
//有一个类,GirlFriend
//只能有一个女朋友
class GirlFriend{
private String name;
//为了能在静态方法中,返回gf对象,将其修饰成static
private static GirlFriend gf = new GirlFriend("红红");
//只能创建一个GirlFriend的对象
//步骤
//1.将构造器私有化
//2.在类的内部直接创建
//3.提供一个static公共方法,返回gf对象
private GirlFriend(String name) {
this.name = name;
}
public static GirlFriend getInstance(){
return gf;
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
懒汉式三部曲(线程不安全)
1.构造器私有化
private Cat(String name) {
this.name = name;
}
2.定义一个static静态属性对象
private static Cat cat;
3.提供一个public的static方法,可以返回一个Cat对象(多线程情况下,多个线程同时new Cat,导致线程不安全,同样可以返回一个对象)
public static Cat getInstance(){
if (cat == null){
//如果没有创建cat对象
cat = new Cat("小可爱");
}
return cat;
}
4.懒汉式,只有用户使用getInstance时,才返回cat对象,再次调用时,会返回上次创建的cat对象(他们会重复使用已有的对象,而懒得去创建)
总代码
public class single2 {
public static void main(String[] args) {
Cat instance = Cat.getInstance();
System.out.println(instance);
}
}
//希望程序运行过程中,只能创建一个猫
//使用单例模式
class Cat{
private String name;
private static Cat cat;
//步骤
//1.构造器私有化
//2.定义一个static静态属性对象
//3.提供一个public的static方法,可以返回一个Cat对象
//4.懒汉式,只有用户使用getInstance时,才返回cat对象,再次调用时,会返回上次创建的cat对象
//保证单调性
private Cat(String name) {
this.name = name;
}
public static Cat getInstance(){
if (cat == null){
//如果没有创建cat对象
cat = new Cat("小可爱");
}
return cat;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
异常-Exception
初识异常代码
(数学运算异常)
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
int res = num1 / num2;
System.out.println("程序继续运行....");
}
解决方案-异常捕获( try-catch)
对异常进行捕获,保证程序可以继续运行. (异常处理机制)
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
//1. num1 / num2 => 10 / 0
//2. 当执行到 num1 / num2 因为 num2 = 0, 程序就会出现抛出异常 ArithmeticException
//3. 当抛出异常后,程序就退出,崩溃了 , 下面的代码就不在执行
//4. 大家想想这样的程序好吗? 不好,不应该出现了一个不算致命的问题,就导致整个系统崩溃
//5. java 设计者,提供了一个叫异常处理机制来解决该问题
// int res = num1 / num2;
//如果程序员,认为一段代码可能出现异常问题,可以使用 try-catch 异常处理机制来解决
//从而保证程序的健壮性
//将该代码块->选中->快捷键 ctrl + alt + t -> 选中 try-catch
//6. 如果进行异常处理,那么即使出现了异常,程序可以继续执行
try {
int res = num1 / num2;
} catch (Exception e) {
//e.printStackTrace();
System.out.println("出现异常的原因=" + e.getMessage());
//输出异常信息 }
System.out.println("程序继续运行....");
}
}
Error and Exception
异常体系图
常见的运行时异常
\1) NullPointerException 空指针异常
\2) ArithmeticException 数学运算异常
\3) ArrayIndexOutOfBoundsException 数组下标越界异常
\4) ClassCastException 类型转换异常
\5) NumberFormatException 数字格式不正确异常[]
\1)NullPointerException 空指针异常
public static void main(String[] args) {
String name = null;
System.out.println(name.length());
}
\2)ArithmeticException 数学运算异常
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
int res = num1 / num2;
System.out.println("程序继续运行....");
}
\3) ArrayIndexOutOfBoundsException 数组下标越界异常
public static void main(String[] args) {
int[] arr = {
1, 2, 3};
for (int i = 0; i <= arr.length; i++) {
System.out.println(arr[i]);
}
}
\4) ClassCastException 类型转换异常
public static void main(String[] args) {
A b = new B(); //向上转型
B b2 = (B) b;//向下转型,这里是 OK
C c2 = (C) b;//这里抛出 ClassCastException
}
class A {
}
class B extends A {
}
class C extends A {
}
\5) NumberFormatException 数字格式不正确异常
public static void main(String[] args) {
String name = "小王学编程"; //将 String 转成 int
int num = Integer.parseInt(name);//抛出 NumberFormatException
System.out.println(num);//1234
}
编译异常
FileNotFoundException
public static void main(String[] args) {
try {
FileInputStream fis;
fis = new FileInputStream("d:\\aa.jpg");
int len;
while ((len = fis.read()) != -1) {
System.out.println(len);
}
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try-catch-finally
public static void main(String[] args) {
//ctrl + atl + t
//1. 如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch 块
//2. 如果异常没有发生,则顺序执行 try 的代码块,不会进入到 catch
//3. 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用如下代码- finally
try {
String str = "小王";
int a = Integer.parseInt(str);
System.out.println("数字:" + a);
} catch (NumberFormatException e) {
System.out.println("异常信息=" + e.getMessage());
} finally {
System.out.println("finally 代码块被执行...");
}
System.out.println("程序继续...");
}
try-catch-finally 执行顺序小结
Integer类:拆箱与装箱
包装类和基本数据的转换和原理
public static void main(String[] args) {
//演示 int <--> Integer 的装箱和拆箱
//jdk5 前是手动装箱和拆箱
//手动装箱 int->Integer
int n1 = 100;
Integer integer = new Integer(n1);
Integer integer1 = Integer.valueOf(n1);
//手动拆箱
// Integer -> int
int i = integer.intValue();
//jdk5 后,就可以自动装箱和自动拆箱
int n2 = 200;
// 自动装箱 int->Integer
Integer integer2 = n2;
// 底层使用的是 Integer.valueOf(n2)
// 自动拆箱Integer->int
int n3 = integer2;
// 底层仍然使用的是 intValue()方法
}
面试题
包装类型和 String 类型的相互转换
public static void main(String[] args) {
//包装类(Integer)->String
Integer i = 100;
//自动装箱
//方式 1
String str1 = i + "";
//方式 2
String str2 = i.toString();
//方式 3
String str3 = String.valueOf(i);
//String -> 包装类(Integer)
String str4 = "12345";
Integer i2 = Integer.parseInt(str4);
//使用到自动装箱
Integer i3 = new Integer(str4);
//构造器
System.out.println("ok~~");
}
Integer 类面试题
public static void main(String[] args) {
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j); //False
//所以,这里主要是看范围 -128 ~ 127 就是直接返回
/* //1. 如果 i 在 IntegerCache.low(-128)~IntegerCache.high(127),就直接从数组返回 //2. 如果不在 -128~127,就直接 new Integer(i) public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } */
Integer m = 1; //底层 Integer.valueOf(1); -> 阅读源码
Integer n = 1;//底层 Integer.valueOf(1);
System.out.println(m == n); //T
//所以,这里主要是看范围 -128 ~ 127 就是直接返回
//,否则,就 new Integer(xx);
Integer x = 128;//底层 Integer.valueOf(1);
Integer y = 128;//底层 Integer.valueOf(1);
System.out.println(x == y);//False
}
public static void main(String[] args) {
//示例一
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2);//F
//示例二
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4);//F
//示例三
Integer i5 = 127;//底层 Integer.valueOf(127)
Integer i6 = 127;//-128~127
System.out.println(i5 == i6); //T
//示例四
Integer i7 = 128;
Integer i8 = 128;
System.out.println(i7 == i8);//F
//示例五
Integer i9 = 127; //Integer.valueOf(127)
Integer i10 = new Integer(127);
System.out.println(i9 == i10);//F
//示例六
Integer i11=127;
int i12=127;
//只有有基本数据类型,判断的是
//值是否相同
System.out.println(i11==i12); //T
//示例七
Integer i13=128;
int i14=128;
System.out.println(i13==i14);//T
}
String 类
String 类的理解和创建对象
public static void main(String[] args) {
//1.String 对象用于保存字符串,也就是一组字符序列
//2."jack" 字符串常量, 双引号括起的字符序列
//3.字符串的字符使用 Unicode 字符编码,一个字符(不区分字母还是汉字)占两个字节
//4.String 类有很多构造器,构造器的重载
//常用的有 String s1 = new String();
//String s2 = new String(String original);
//String s3 = new String(char[] a);
//String s4 = new String(char[] a,int startIndex,int count)
//String s5 = new String(byte[] b)
//5. String 类实现了接口 Serializable【String 可以串行化:可以在网络传输】
//接口 Comparable [String 对象可以比较大小]
//6. String 是 final 类,不能被其他的类继承
//7. String 有属性 private final char value[]; 用于存放字符串内容
//8. 一定要注意:value 是一个 final 类型, 不可以修改(需要功力):即 value 不能指向
//新的地址,但是单个字符内容是可以变化
String name = "jack";
name = "tom";
System.out.println(name);
final char[] value = {
'a','b','c'};
char[] v2 = {
't','o','m'};
value[0] = 'H';
//value = v2; 不可以修改 value 地址
}