15-初始化和清理
初始化和清理初始化和清理是涉及编程安全的两个重要问题,在C语言中一直采取由程序员直接控制变量的初始化和清理,极易导致内存耗尽等问题出现
C++和Java采用了构造器(构造方法)的概念来进行对象的创建,创建对象时,如果该类提供有构造方法,Java会在用户有能力操作对象前调用构造器,完成对类中每个对象的初始化
构造器与类同名的原因
调用构造器是编译器的任务,所以编译器必须清楚要调用哪个方法,这就要求所有类的构造器必须具有相同的方法名
所取的任何名字都可能与类中原有的方法名重复,产生冲突,为了避免这种情况,统一采用构造器与类同名这种方案
构造器没有返回值,这与返回值为空null(void)具有很大区别,构造器本质上不会返回任何东西,我们在创建对象时Object object=new Object();看似是构造方法返回了一个新对象,实质是new表达式返回了该对象的引用(虽然与该对象完全一致)。
因为有了构造器的存在,所以强制重载方法名就显得十分重要,这也是Java支持强制重载方法名的重要原因。区分重载方法的唯一规则是不同的参数列表(即便只是顺序不同),而返回值并不可以作为区分重载方法的规则 ...
14-IO流
字符集各个国家为自己国家的字符取的一套编号规则,计算机底层只能存储二进制,二进制可以转成十进制,十进制可以进行整数编号,所以计算机底层可以存储编号规则
I/O流的分类与概述(IO输入输出流-Input/Output)
File类只能操作文件对象本身,并不能操作文件的内容(对文件内容进行读/写)。如果需要读写数据的操作,就需要使用I/O流
I/O流的分类按照流的方向来分
输入流:已内存为基准,把内存中的数据写出到磁盘文件或者网络介质中去的流称为输入流。例如:将数据写入文件
输出流:以内存为基准,把磁盘文件中的数据或者网络中的数据读入到内存中去的流称为输入流。输入流的作用就是读取数据到内存
按照流的内容来分
字节流:流中的数据最小单位是一个一个的字节,这个流就是字节流
字符流:流中的数据最小单位是一个一个的字符,这个流就是字符流
FileInputStream-文件字节输入流以内存为基准,将磁盘文件中的数据按照字节的形式读入到内存中的流,简单来说,就是按照字节读取文件数据到内存构造器
public FileInputStream(File path):创建一个字节输入流管道与源文件对 ...
13-递归
递归概念递归指方法在方法中又调用自己递归形式直接递归自己的放大中调用自己
间接递归A方法调用B方法,B方法又调用A方法
递归三要素1. 一定有终止条件2. 递归的规则/公式3. 递归的方向:必然走向终止条件递归搜索文件12345678910111213141516171819202122232425package FileDemo;import java.io.File;public class FileDemo1 { public void findFile(File f){ if(f.isFile()){ System.out.println(f.getName()); } else{ System.out.println("文件夹----------------------"+f.getName()+"----------------------文件夹"); for(File f ...
12-File类
File类概述File类代表操作系统的文件对象,是用来操作操作系统中的文件对象的,例如:删除文件,获取文件信息,创建文件/文件夹。广义来说,操作系统认为文件已经包含了文件和文件夹的概念
构造器
public File(String pathname):根据路径获取文件对象
public File(String parent,String child):根据父路径和文件名称获取文件对象
public File(File parent,String child):根据父类文件对象和子类文件名称获取子类文件对象
这里的路径也是分为绝对路径和相对路径,Java默认的相对路径是相对工程目录下的文件路径。二者比较而言,绝对路径一旦脱离具体依赖的环境,代码就极可能出错。相对路径在脱离所处的环境后一般还是可以正常执行,但相对路径只能用于寻找该工程下的文件,有一定的局限性。一般为了跨平台操作,主要采用相对路径
文件路径分隔符
可以使用正斜杠“/”
使用反斜杠(需要转义)“\\”
使用分隔符API:File.separator
123456//方式1:使用正斜杠File f1=new File(&qu ...
11-Stream流
Stream流的概述概念得益于Lambda所带来的函数式编程,用于解决已有集合/数组类库有的弊端
用途解决已有集合类库或者数组API的弊端
实例1234567891011121314151617181920212223242526272829package StreamDemo;import java.util.ArrayList;import java.util.List;public class StreamDemo1 { public static void main(String[] args) { List<String> lists = new ArrayList<>(); lists.add("Leslie"); lists.add("Lily"); lists.add("Leon"); lists.add("John"); lists.add("Li"); lists.add(&q ...
10-方法引用
方法引用概述目的方法引用是为了进一步简化Lambda表达式的写法
格式1类型或对象::引用的方法 //关键语法 “::”
实例123456789101112131415161718package ComparatorDemo;import java.util.ArrayList;import java.util.List;public class MethodDemo { public static void main(String[] args) { List<String> lists=new ArrayList<>(); lists.add("first"); lists.add("second"); lists.add("third"); //遍历列表,通过Lambda表达式的方法 lists.forEach(s -> System.out.println(s)); ...
9-Lambda表达式
匿名内部类没有名字的局部内部类,匿名内部类的目的是为了简化代码。
格式123new 类名|抽象类|接口(形参){ 方法重写......}
实例12345678910111213141516171819202122232425package Anonymity;abstract class Task{ public void func(){ System.out.println("这是父类的func方法"); } //定义抽象方法 public abstract void func2();}public class Demo1 { //匿名内部类 public static Task t=new Task() { //重写抽象方法 @Override public void func2() { System.out.println("这是匿名内部类重 ...
8-并发包
并发包概念在实际开发中不考虑线程安全的情况下,一般不需要做线程安全处理,防止过多的处理导致性能变差
但是开发中有很多业务需要考虑线程安全的相关问题,此时就必须考虑线程安全的处理
Java为很多业务场景提供了性能优异,且线程安全的并发包
ConcurrentHashMap12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364package ConcurrentHashMap;import java.util.HashMap;import java.util.Hashtable;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;public class CHMDemo1 { //public static Map<String,String> maps=new HashMap<>(); ...
7-volatile关键字
并发编程下,多线程访问变量的不可见性问题指多个线程访问共享变量,会出现一个线程修改变量的值后,其他线程看不到最新值的情况
代码示例:12345678910111213141516171819202122232425262728293031323334353637package VolatileTest;public class VolatileDemo extends Thread{ private boolean flag=false; @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } flag=true; System.out.println("flag修改成功!"); } p ...
6-死锁
死锁死锁代表的是一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期阻塞,因此程序不可能正常终止(例如:客户一方占用资金等待货物资源,经销商一方占用货物资源等待资金,双方都占用一种资源,并且都在等待一种资源,这就导致交易流程无法正常进行,也就形成了所谓的“死锁”)
死锁产生的四个必要条件:
互斥使用:即当一个资源被一个一个线程使用(占有)时,别的线程不能使用
不可抢占:资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放
请求和保持:即当资源请求者在请求其他的资源的同时保持对原有资源的占有
循环等待:即存在一个等待循环队列,P1要P2的资源,P2要P1的资源,这样就形成了一个等待循环
当上述的四个条件都满足时,便形成死锁,当然,死锁的情况下如果打破上述任何一个条件,便可以让死锁消失。开发中应该尽量避免死锁
死锁在代码形式上通常需要锁的嵌套,也就是在锁的内部还有锁
代码实现:必然死锁的案例12345678910111213141516171819202122232425262728293031323334353637383940 ...