JavaSE进阶笔记
Static
· static是静态的意思,可以修饰成员变量和成员方法。
· static修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改。
- 成员变量的分类和访问分别是什么样的?
1 2 3 4 5
| 静态成员变量(有static修饰,属于类、加载一次,可以被共享访问),访问格式 类名.静态成员变量(推荐) 对象.静态成员变量(不推荐)。 实例成员变量(无static修饰,属于对象),访问格式: 对象.实例成员变量。
|
- 两种成员变量各自在什么情况下定义?
1 2
| 静态成员变量:表示在线人数等需要被共享的信息。 实例成员变量:属于每个对象,且每个对象信息不同时(name,age,…等)
|
- 成员方法的分类和访问分别是什么样的?
1 2 3 4 5
| 静态成员方法(有static修饰,属于类和对象共享)访问格式: 类名.静态成员方法。 对象.静态成员方法。(不推荐) 实例成员方法(无static修饰,属于对象)的访问格式: 对象.实例成员方法。
|
- 每种成员方法的使用场景是怎么样的?
1 2
| ·表示对象自己的行为的,且方法中需要访问实例成员的,则该方法必须申明成实例方法。 ·如果该方法是以执行一个通用功能为目的,或者需要方便访问,则可以申明成静态方法
|
- 工具类是什么,有什么好处?
1 2
| ·内部都是一些静态方法,每个方法完成一个功能 ·一次编写,处处可用,提高代码的重用性。
|
- 工具类有什么要求?
1 2
| ·建议工具类的构造器私有化处理。 ·工具类不需要创建对象。
|
- static访问注意?
1 2 3
| ·静态方法只能访问静态的成员,不可以直接访问实例成员。 ·实例方法可以访问静态的成员,也可以访问实例成员。 ·静态方法中是不可以出现this关键字的。
|
代码块
· 代码块是类的5大成分之一(成员变量、构造器,方法,代码块,内部类),定义在类中方法外。
· 在Java类下,使用 { } 括起来的代码被称为代码块 。
1 2 3 4 5 6 7 8 9 10
| 代码块分为 静态代码块: 格式:static{} 特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发、只执行一次 使用场景:在类加载的时候做一些静态数据初始化的操作,以便后续使用。 --------------- 构造代码块(了解,用的少): 格式:{} 特点:每次创建对象,调用构造器执行时,都会执行该代码块中的代码,并且在构造器执行前执行 使用场景:初始化实例资源。
|
- 静态代码块的作用?
1 2
| ·如果要在启动系统时对数据进行初始化。 ·建议使用静态代码块完成数据的初始化操作,代码优雅。
|
final
- final的作用
1 2 3 4
| ·final 关键字是最终的意思,可以修饰(方法,变量,类) ·修饰方法:表明该方法是最终方法,不能被重写。 ·修饰变量:表示该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)。 ·修饰类:表明该类是最终类,不能被继承。
|
- 常量的执行原理
1 2
| · 在编译阶段会进行“宏替换”,把使用常量的地方全部替换成真实的字面量。 · 这样做的好处是让使用常量的程序的执行性能与直接使用字面量是一样的。
|
- final修饰变量的注意
1 2 3
| · final修饰的变量是基本类型:那么变量存储的数据值不能发生改变。 · final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的 (数组)
|
枚举
· 枚举是Java中的一种特殊类型
· 枚举的作用:”是为了做信息的标志和信息的分类”。
- 定义枚举类的格式
1 2 3
| enum Season{ SPRING , SUMMER , AUTUMN , WINTER; }
|
反编译后结果:
1 2 3 4 5 6 7 8 9
| Compiled from "Season.java" public final class Season extends java.lang.Enum<Season> { public static final Season SPRING = new Season(); public static final Season SUMMER = new Season(); public static final Season AUTUMN = new Season(); public static final Season WINTER = new Season(); public static Season[] values(); public static Season valueOf(java.lang.String); }
|
- 枚举的特征:
1 2 3 4 5
| ·枚举类都是继承了枚举类型:java.lang.Enum ·枚举都是最终类,不可以被继承。 ·构造器都是私有的,枚举对外不能创建对象。 ·枚举类的第一行默认都是罗列枚举对象的名称的。 ·枚举类相当于是多例模式。
|
抽象类
- 概念
1
| 在Java中abstract是抽象的意思,如果一个类中的某个方法的具体实现不能确定,就可以申明成abstract修饰的抽象方法(不能写方法体了),这个类必须用abstract修饰,被称为抽象类。
|
- 抽象的使用总结与注意事项
1 2 3 4
| · 抽象类可以理解成类的不完整设计图,是用来被子类继承的。 · 一个类如果继承了抽象类,那么这个类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类 · 失去了创建对象的能力 · 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
|
- 抽象类的作用
1 2 3
| ·可以被子类继承 ·充当模板的 ·同时也可以提高代码复用
|
4 .final和abstract的关系
1 2
| · abstract定义的抽象类作为模板让子类继承,final定义的类不能被继承。 · 抽象方法定义通用功能让子类重写,final定义的方法子类不能重写。
|
接口
注意事项
1 2 3 4 5
| 1、接口不能创建对象 2、一个类实现多个接口,多个接口中有同样的静态方法不冲突。 3、一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的。 4、一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可。 5、一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承。
|
内部类
静态内部类
- 静态内部类中是否可以直接访问外部类的静态成员? yes
- 静态内部类中是否可以直接访问外部类的实例成员? no
- 静态内部类的使用场景、特点、访问总结
1 2 3 4
| ·如果一个类中包含了一个完整的成分,如汽车类中的发动机类。 ·特点、使用与普通类是一样的,类有的成分它都有,只是位置在别人里面而已。 ·可以直接访问外部类的静态成员,不能直接访问外部类的实例成员。 ·注意:开发中实际上用的还是比较少。
|
成员内部类
- 成员内部类中是否可以直接访问外部类的静态成员? yes
- 成员内部类中是否可以直接访问外部类的实例成员? yes
匿名内部类
单例模式
· 可以保证系统中,应用该模式的这个类永远只有一个实例,即一个类永远只能创建一个对象。
· 例如任务管理器对象我们只需要一个就可以解决问题了,这样可以节省内存空间。
- 饿汉单例设计模式
1 2 3 4 5
| · 在用类获取对象的时候,对象已经提前为你创建好了。
设计步骤: · 定义一个类,把构造器私有。 · 定义一个静态变量存储一个对象。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class SingleInstance { public static SingleInstance instance = new SingleInstance (); private SingleInstance (){ System.out.println("创建了一个对象"); } }
|
- 懒汉单例设计模式
1 2 3 4 5 6 7
| · 在真正需要该对象的时候,才去创建一个对象。
设计步骤: · 定义一个类,把构造器私有。 · 定义一个静态变量存储一个对象。 · 提供一个返回单例对象的方法
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class SingleInstance2 {
private static SingleInstance2 instance;
private SingleInstance2(){ }
public static SingleInstance2 getInstance(){ if(instance == null){ instance = new SingleInstance2(); } return instance; } }
|
继承
- 继承有哪些特点
1 2 3 4
| · 子类可以继承父类的属性和行为,但是子类不能继承父类的构造器。 · Java是单继承模式:一个类只能继承一个直接父类。 · Java不支持多继承、但是支持多层继承。 · Java中所有的类都是Object类的子类。
|
- 在子类方法中访问成员(成员变量、成员方法)满足:就近原则
1 2 3
| · 先子类局部范围找 · 然后子类成员范围找 · 然后父类成员范围找,如果父类范围还没有找到则报错。
|
- 如果子父类中,出现了重名的成员,会优先使用子类的,此时如果一定要在子类中使用父类的怎么办?
多态
- 多态的常见形式
1 2
| 父类类型 对象名称 = new 子类构造器 接口 对象名称 = new 实现类构造器
|
- 多态中成员访问特点
1 2
| · 方法调用:编译看左边,运行看右边。 · 变量调用:编译看左边,运行也看左边
|
- 多态的数据类型的数据转换
1 2 3 4 5 6 7
| 引用数据类型的类型转换,有几种方式? ·自动类型转换、强制类型转换。 强制类型转换能解决什么问题?强制类型转换需要注意什么。 ·可以转换成真正的子类类型,从而调用子类独有功能。 ·有继承关系/实现的2个类型就可以进行强制转换,编译无问题。 ·运行时,如果发现强制转换后的类型不是对象真实类型则报错。 ·类型转换异常:ClassCastException
|
常用API
toString
· 作用: 让子类重写,以遍返回子类对象的内容
equals
· 默认是与另一个对象比较地址是否一样
· 让子类重写,以便比较2个子类对象的内容是否相同
StringBuilder
Math
System
BigDecimal
Date
1 2 3 4 5 6
| 1、日期对象如何创建,如何获取时间毫秒值? public Date(); public long getTime(); 2、时间毫秒值怎么恢复成日期对象 public Date(long time); public void setTime(long time);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class SimpleDateFormatDemo01 { public static void main(String[] args) { Date d = new Date(); System.out.println(d);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a"); String rs = sdf.format(d); System.out.println(rs);
System.out.println("----------------------------");
long time1 = System.currentTimeMillis() + 121 * 1000; String rs2 = sdf.format(time1); System.out.println(rs2);
System.out.println("------------解析字符串时间,下个代码---------------"); -------------------------------------- String dateStr = "2021年08月06日 11:11:11";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); Date d = sdf.parse(dateStr);
long time = d.getTime() + (2L*24*60*60 + 14*60*60 + 49*60 + 6) * 1000;
System.out.println(sdf.format(time)); } }
|
Calendar
Arrays
XML
基础知识
- xml的作用
1 2
| · 用于进行存储数据和传输数据 · 作为软件的配置文件
|
- XML的文档约束-DTD的作用和问题?
1 2
| · 可以约束XML文件的编写。 · 不能约束具体的数据类型。
|
- XML的文档约束-schema的优点?
1 2
| · 可以约束XML文件的标签内容格式,以及具体的数据类型。 · 本身也是xml文件,格式更严谨。
|
XML解析技术-Dom4J
- Dom解析的文档对象模型是怎么样的
- Dom4J的解析思想?
1
| · 得到文档对象Document,从中获取元素对象和内容
|
- Dom4J的解析后的数据形式?
1
| · 通常数据会封装成Java的对象,如单个对象,或者集合对象形式
|
XML检索技术-XPath
- 如果需要从XML文件中检索需要的某个信息(如name)怎么解决?
1 2
| · Dom4j需要进行文件的全部解析,然后再寻找数据。 · Xpath技术更加适合做信息检索。
|
- XPath作用
1 2 3 4 5
| ---检索XML文件中的信息 绝对路径: /根元素/子元素/孙元素 相对路径:./子元素/孙元素 全文检索://contact 属性查找://@属性名 、//元素[@属性名]、//元素//[@属性名=‘值’]
|
设计模式
工厂模式
- 什么是工厂设计模式?
1
| 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种获取对象的方式。
|
- 工厂设计模式的作用:
1 2
| · 工厂的方法可以封装对象的创建细节,比如:为该对象进行加工和数据注入。 · 可以实现类与类之间的解耦操作(核心思想)。
|
装饰模式
- 什么是装饰模式
1
| 创建一个新类,包装原始类,从而在新类中提升原来类的功能。
|
- 装饰模式的作用
1 2 3 4 5 6
| 装饰模式指的是在不改变原类的基础上, 动态地扩展一个类的功能。
example: InputStream(抽象父类) FileInputStream(实现子类,读写性能较差) BufferedInputStream(实现子类,装饰类,读写性能高)
|
- 设计步骤
1 2 3
| · 定义父类。 · 定义原始类,继承父类,定义功能。 · 定义装饰类,继承父类,包装原始类,增强功能!!
|
正则表达式
包装类
JDK8新增日期类
集合
- 集合的代表是?
- Collection集合分了哪两种常用的集合体系?
1 2 3 4 5
| List系列集合:添加的元素是有序、可重复、有索引。 Set系列集合:添加的元素是无序、不重复、无索引。 HashSet(哈希表): 无序、不重复、无索引。 LinkedHashSet(哈希表+双链表):有序、不重复、无索引 TreeSet(红黑树):排序、不重复、无索引。
|
- 常用API
- 集合的遍历的方式
1 2 3 4 5 6 7 8 9 10 11 12 13
| 1.迭代器
Iterator<String> it= lists.iterator(); while(it.hasNext()){ String ele=it.next(); System.out.println(ele); }
2.for循环 for (String ele : lists) { System.out.println(ele); }
|
- 集合中存储的是元素的什么信息?
- List集合特有方法
- List的实现类的底层原理
1 2
| · ArrayList底层是基于数组实现的,根据查询元素快,增删相对慢。 · LinkedList底层基于双链表实现的,查询元素慢,增删首尾元素是非常快的
|
- LinkedList特有功能
- 泛型
1 2 3 4 5 6 7 8 9 10 11
| (1)泛型类(方法)核心思想: 把出现泛型变量(方法)的地方全部替换成传输的真实数据类型 (2)泛型类的作用 编译阶段约定操作的数据的类型,类似于集合的作用。 (3)泛型方法的作用 方法中可以使用泛型接收一切实际类型的参数,方法更具备通用性 (4)泛型接口的作用 泛型接口可以约束实现类,实现类可以在实现接口的时候传入自己操作的数据类型这样重写的方法都将是针对于该类型的操作。 (5)泛型的上下限 · ? extends Car: ?必须是Car或者其子类 泛型上限 · ? super Car : ?必须是Car或者其父类 泛型下限
|
- 如果希望Set集合认为2个内容相同的对象是重复的应该怎么办?
- TreeSet集合自定义排序规则
1 2
| · 类实现Comparable接口,重写比较规则 · 自定义Comparator比较器对象,重写比较规则
|
- Collections集合工具类
作用: Collections并不属于集合,是用来操作集合的工具类
常用API:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public static <T> boolean addAll(Collection<? super T> c, T... elements)
List<String> names = new ArrayList<>(); Collections.addAll(names, "楚留香","胡铁花", "张无忌","陆小凤");
public static void shuffle(List<?> list)
Collections.shuffle(names);
public static <T> void sort(List<T> list)
Collections.sort(list);
public static <T> void sort(List<T> list,Comparator<? super T> c)
List<Apple> apples = new ArrayList<>(); apples.add(new Apple("红富士", "红色", 9.9, 500)); apples.add(new Apple("青苹果", "绿色", 15.9, 300)); apples.add(new Apple("绿苹果", "青色", 29.9, 400)); apples.add(new Apple("黄苹果", "黄色", 9.8, 500)); Collections.sort(apples, new Comparator<Apple>() { @Override public int compare(Apple o1, Apple o2) { return Double.compare(o1.getPrice() , o2.getPrice()); } });
|
不可变集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| List<Double> lists = List.of(569.5, 700.5, 523.0, 570.5);
System.out.println(lists);
double score = lists.get(1); System.out.println(score);
Set<String> names = Set.of("迪丽热巴", "迪丽热九", "马尔扎哈", "卡尔眨巴" ); names.add("三少爷"); System.out.println(names);
Map<String, Integer> maps = Map.of("huawei",2, "Java开发", 1 , "手表", 1);
System.out.println(maps);
|
可变参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class MethodDemo { public static void main(String[] args) {
sum(); sum(10); sum(10, 20, 30); sum(new int[]{10, 20, 30, 40, 50}); }
public static void sum( int...nums){ System.out.println("元素个数:" + nums.length); System.out.println("元素内容:" + Arrays.toString(nums)); } }
|
Map
Map的三种遍历方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class MapDemo01 { public static void main(String[] args) { Map<String, Integer> maps = new HashMap<>(); maps.put("娃娃", 30); maps.put("iphoneX", 100); maps.put("huawei", 1000); maps.put("生活用品", 10); maps.put("手表", 10); System.out.println(maps);
Set<String> keyset = maps.keySet(); for (String key : keyset) { int value = maps.get(key); System.out.println(key + "---->" + value); } System.out.println("----------"); Set<Map.Entry<String, Integer>> entries = maps.entrySet(); for (Map.Entry<String, Integer> entry : entries) { String key = entry.getKey(); int value = entry.getValue(); System.out.println(key + "---->" + value); } System.out.println("----------"); maps.forEach((k, v) -> { System.out.println(k + "--->" + v); }); } }
|
Stream流
目的
用于简化集合和数组操作的API
Stream流的思想和使用步骤
· 先得到集合或者数组的Stream流(就是一根传送带)。
· 把元素放上去。
· 然后就用这个Stream流简化的API来方便的操作元素。
获取Stream流的方式
常用API
常用终结方法
收集Stream流
含义
把Stream流操作后的结果数据转回到集合或者数组中去
收集方式
作用
· Stream流是操作集合数组的手段
· 操作的结果数据最终要恢复到集合或者数组中
File
File类创建对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| File f = new File("D:" + File.separator+"a"+ File.separator +"b.jpg"); long size = f.length(); System.out.println(size);
File f1 = new File("D:\\a\\c.jpeg"); System.out.println(f1.length());
File f2 = new File("file-io-app/src/data.txt"); System.out.println(f2.length());
File f3 = new File("D:\\a"); System.out.println(f3.exists());
|
相关API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| System.out.println(f1.length()); --------------------------------------------------------------------------------- File f = new File("file-io-app\\src\\data.txt"); System.out.println(f.createNewFile()); File f1 = new File("file-io-app\\src\\data02.txt"); System.out.println(f1.createNewFile());
File f2 = new File("D:/resources/aaa"); System.out.println(f2.mkdir());
File f3 = new File("D:/resources/ccc/ddd/eee/ffff"); System.out.println(f3.mkdirs());
System.out.println(f1.delete()); File f4 = new File("D:/resources/xueshan.jpeg"); System.out.println(f4.delete());
File f5 = new File("D:/resources/aaa"); System.out.println(f5.delete());
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
public class FileDemo04 { public static void main(String[] args) { File f1 = new File("D:/resources"); String[] names = f1.list(); for (String name : names) { System.out.println(name); }
File[] files = f1.listFiles(); for (File f : files) { System.out.println(f.getAbsolutePath()); }
File dir = new File("D:/resources/ddd"); File[] files1 = dir.listFiles(); System.out.println(Arrays.toString(files1)); } }
|
字符集的解码,编码操作
IO流
四大类
· 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流称为字节输入流。
· 字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流称为字节输出流。
· 字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流称为字符输入流。
· 字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流称为字符输出流
作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去。
避免乱码问题
文件字节输出流:FileOutputStream
作用:以内存为基准,把内存中的数据以字节的形式写出到磁盘文件中去的流。
资源释放的处理方式
第一种方式
- try-catch-finally的作用
finally代码块是最终一定要执行的,可以在代码执行完毕的最后用于释放资源。
第二种方式
文件字符输入流: Reader
文件字符输出流: Writer
字节缓冲流
- 为什么提高了操作数据的性能?
· 字节缓冲流自带8KB缓冲区
· 可以提高原始字节流、字符流读写数据的性能
- 推荐使用哪种方式提高字节流读写数据的性能?
· 建议使用字节缓冲输入流、字节缓冲输出流,结合字节数组的方式
字符缓冲流
字符缓冲输入流
字符缓冲输出流
转换流
- 为什么会有转换流
1 2
| · 如果代码编码和文件编码不一致,使用字符流直接读取会乱码 · 文件编码和读取的编码必须一致才不会乱码
|
- 如何解决
1 2 3
| · 使用字符输入转换流 · 可以提取文件的原始字节流,原始字节不会存在问题。 · 然后把字节流以指定编码转换成字符输入流,这样字符输入流中的字符就不乱码了
|
- 字符输入转换流InputStreamReader作用:
1 2 3
| · 可以读取不同编码乱码的问题 · public InputStreamReader(InputStream is,String charset): 可以指定编码把原始字节流转换成字符流,如此字符流中的字符不乱码。
|
- 如果需要控制写出去的字符使用的编码,怎么办?
1 2
| ·可以把字符以指定编码获取字节后再使用字节输出流写出去:“我爱你中国”.getBytes · 也可以使用字符输出转换流实现。
|
- 字符输出转换流OutputStreamWriter的作用?
1
| 可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码!
|
对象字节输出流-ObjectOutputStream(对象序列化)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public static void main(String[] args) throws Exception { Student s = new Student("xx", "chenlei","1314520", 21);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io-app2/src/obj.txt"));
oos.writeObject(s);
oos.close(); System.out.println("序列化完成了~~");
}
|
- 对象序列化的含义
- 序列化对象的要求
1 2 3 4 5 6 7 8 9
| public static void main(String[] args) throws Exception { ObjectInputStream is = new ObjectInputStream(new FileInputStream("src/obj.txt"));
Student s = (Student) is.readObject();
System.out.println(s); }
|
打印流
输出语句重定向
Properties属性集对象
核心作用
1 2
| · Properties代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。 · 属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value,后续做系统配置信息的。
|
相关API
example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static void main(String[] args) throws Exception { Properties properties = new Properties(); properties.setProperty("admin", "123456"); properties.setProperty("dlei", "003197"); properties.setProperty("heima", "itcast"); System.out.println(properties);
properties.store(new FileWriter("src/users.properties") , "this is users!! i am very happy! give me 100!");
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static void main(String[] args) throws Exception { Properties properties = new Properties(); System.out.println(properties);
properties.load(new FileReader("io-app2/src/users.properties"));
System.out.println(properties); String rs = properties.getProperty("dlei"); System.out.println(rs); String rs1 = properties.getProperty("admin"); System.out.println(rs1); }
|
commons-io