文章目录
- 1. Java开发基础
- 1.1 DOS常用命令:(以MAC常用命令比较)
- 1.2 JVM、JRE、JDK之间的关系
- 1.3 Java开发环境的搭建
- 1.4 Java的注释,标识符、标识符的命名规范
- 1.5 变量和常量的定义及初始化
- 1.6 Java的运算符
- 1.7 三大语句
- 1.8 常用的类
- 1.8.1 java.lang.Object 老祖宗:
- 1.8.2 java.lang.String
- 1.8.3 java.lang.Math
- 2. Java数组
- 2.1 Java 数组的定义
- 2.2 数组顺序查找
- 2.3 数组冒泡排序
- 2.4 Arrays工具类的使用
- 3. Java面向对象
- 3.1 简介
- 3.2 继承
- 3.3 多态
- 3.4 抽象
- 3.5 接口与抽象类
- 4. 异常
- 5. 范型
- 6. IO流
- 7. 多线程
- 7.1 进程和线程的介绍
- 7.2 线程三态转化
- 7.3 创建线程和启动
- 7.4 线程管理
- 7.5 线程池
- 8. 反射
1. Java开发基础
1.1 DOS常用命令:(以MAC常用命令比较)
常用命令 | DOS | MAC |
---|---|---|
切换盘符(更换路径) | D: | cd / |
进入文件夹 | cd D:/Java/Demo | cd /Java/Demo |
返回上一级目录 | cd … | cd … |
查看文件夹内容 | dir | ls -alh |
清屏 | cls | clear |
推出 | exit | exit |
1.2 JVM、JRE、JDK之间的关系
jdk:Java Development kit(Java开发工具包)
jre:Java Runing Environment(Java运行环境)
jvm:java Virtual Machine(Java虚拟机)
JDK 主要包含Jre+Javac编译器+Java解释器
Java的类库(3600多)
JAVA源文件(.java)
JAVA字节码文件(.class) 由JAVA编译器(javac.exe)编译完成
由解释执行器(Java.exe)将字节码文件加载到Java虚拟机(jvm)执行
1.3 Java开发环境的搭建
MAC配置环境变量(十分详细)
https://www.cnblogs.com/52py/p/8065066.html
1、 根据自己的系统在Oracle官网下载jdk并安装
2、 此时jdk安装在MAC系统的目录:
/Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home
3、 进行配置环境变量:(MAC与Win不一样)如果你是第一次配置环境变量,可以使用“touch .bash_profile” 创建一个.bash_profile的隐藏配置文件(如果你是为编辑已存在的配置文件,则使用"open -e .bash_profile"命令)
4、 在 .bash_profile添加以下配置内容
JAVA_HOME=/Library/Java/JavaVirtualMachines/ jdk-9.0.4.jdk /Contents/Home
PATH=$JAVA_HOME/bin:$PATH:.
CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.
export JAVA_HOME
export PATH
export CLASSPATH
1.4 Java的注释,标识符、标识符的命名规范
单行注释 // 以及 /* */
多行注释 不可以嵌套
/*
*
*/
标识符(字母、数字、下划线_、美元符$){
-不能以数字开头
-不用使用关键字或者保留字为标识符
(1)采用驼峰命名法(即所有单词的首字母大写) (驼峰法)myCar
(2)下划线法 my_car
(3)MyCar
}
PS:关键字都是小写,TRUE、FALSE、NULL不是关键字
八种基本数据类型:
byte(1B)、short(2B)、int(4B)、long(8B)、
float(4B)、double(8B)、boolean(1B)、char(2B)
基本类型 包装类(引用类型,位于java.lang )
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
引用数据类型:String、数组、类、接口、枚举、Lamda
1.5 变量和常量的定义及初始化
Java语言支持的变量类型有:
局部变量:类的方法中的变量
成员变量:独立于方法之外的变量,不过没有 static 修饰。
类变量:独立于方法之外的变量,用 static 修饰。
全局变量:整个文件都可以使用该变量。常量的分类:final
1、 字符串常量。final String s=“zhupeng”
2、 整数常量。 final int a=100
3、 浮点数常量。 final double PI = 3.1415926D
4、 字符常量。 final char c = ‘c’
5、 布尔常量。 final boolean Bool = true
6、 空常量
注意:当定义的final变量属于“成员变量”时,必须在定义时就设定它的初始值,否则将会产生编译错误。
1.6 Java的运算符
算术运算符:+、—、*、/、%、++、--
关系运算符:==、!=、>、< 、>=、<=
位运算符:不会截断A?B一定判断
& 如果相对应位都是1,则结果为1,否则为0 (A&B)
| 如果相对应位都是0,则结果为0,否则为1 (A | B)
^ 如果相对应位值相同,则结果为0,否则为1 (A ^ B)
〜 按位取反运算符翻转操作数的每一位,即0变成1,1变成0
<< 带符号按位左移运算符,低位补0
>> 带符号按位右移运算符,正数高位补0,负数低位补1。
>>> 不带符号按位右移补零操作符
没有<<<
逻辑运算符:(会发生截断)
A && B:逻辑与运算符。当且仅当两个操作数都为真,条件才为真。(若A为false,B不执行,若A为true,B执行)
A | | B:逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。(若A为false,B执行;若A为true,B不执行)
! 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。
赋值运算符:
=、+ =、- = 、* =、/ =、%=
其他运算符:
条件运算符(?:)例:b = (a == 1) ? 20 : 30;从右到左
instanceof 运算符:该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)
String name = "James";
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
1.7 三大语句
Java判断语句
a、if-else语句
if(布尔表达式){
//如果布尔表达式的值为true
}else{
//如果布尔表达式的值为false
}
b、if-else if-else语句
if(布尔表达式 1){
//如果布尔表达式 1的值为true执行代码
}else if(布尔表达式 2){
//如果布尔表达式 2的值为true执行代码
}else if(布尔表达式 3){
//如果布尔表达式 3的值为true执行代码
}else {
//如果以上布尔表达式都不为true执行代码
}
c、switch语句
expression表达式的类型只能是:byte、short、int、char及其包装类,Java8之后支持String、enum
switch(expression){
case value :
//语句
break; //可选
case value :
//语句
break; //可选
default : //可选
//语句
}
Java循环语句
a、while语句
while( 布尔表达式 ) {
//循环内容
}
b、do-while语句
do {
//代码语句
}while(布尔表达式);
c、for语句
for(初始化; 布尔表达式; 更新) {
//代码语句
}
方法的定义
方法的命名规则
1.方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。
一般情况下,定义一个方法包含以下语法:
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
修饰符: 修饰符,定义了该方法的访问类型 public protected private default…
返回值类型: 方法可能会返回值 void int float…
方法名: 是方法的实际名称。
参数类型: 参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。
方法体: 方法体包含具体的语句,定义该方法的功能。
1.8 常用的类
1.8.1 java.lang.Object 老祖宗:
所有的类直接或者间接继承父类,Java认为所有的对象都具备一些基本的共性内容 这些内容可以不断的向上抽取 最终就抽取到了一个最顶层的类中(Object) 该类中定义的就是所有对象都具备的功能。Object的常用方法没有sleep()、synchronized ()、join()。常见的有:wait() notify() notifyAll() finalize()
1.8.2 java.lang.String
1、四种构造方法
public String()
public String(char[] array)
public String(byte[] array)
直接创建
//空参构造
String str1=new String(“zhu”);
System.out.println("第一个字符串:"+str1);
//字符数组构造
char[] charaArray={'z','h','u'};
String str2=new String(charArray);
System.out.println("第二个字符串:"+str2);
//字节数组构造
byte[] bytearray={97,98,99};
String str3=new String(bytearray);
System.out.println("第三个字符串:"+str3);
//直接创建
String str4="zhu";
System.out.println("第四个字符串:"+str4);
2、equals( ) 字符串比较
System.out.println(str2.equals(str4));//字符串内容比较
3、length( ) 字符串长度
int len = s2.length();
4、concat( )连接字符串
String s3=s1.concat(s2);
5、charAt(index) 返回指定索引处的 char 值。
s3.charAt(0));
6、indexOf(“abc”) 查找字符串第一次出现的下标
s3.indexOf("z"));
7、substring(begin,end) 截取字符串[begin,end)
String s4=s3.substring(0,4);
8、toCharArray()字符串转为字符数组
String s5="zhuzhuzhu";
char[] cc=s5.toCharArray();
9、getBytes()字符串转为字节数组
byte[] bb=s5.getBytes();
for (int i=0;i<bb.length ; i++) {
System.out.printf(" %d ",bb[i]);
}
10、replace(old,new)替换,用于敏感词替换
String s6="你是个傻逼,傻逼";
String s7=s6.replace("逼","*");
11、split()将数组切换
String s8="173-149-75-786";
String[] array2=s8.split("-");
12、将整型转为字符串
//String s=String.valueOf(number);
//String s=Integer.toString(number);
//s+=””
13、将字符串转为整形
Integer.parseInt(“123”)
Float.parseFloat(“1.23”)
1.8.3 java.lang.Math
public class test{
public static void main(String []args){
//1、compareTo:用于将 Number 对象与方法的参数进行比较,可用于比较 Byte, Long, Integer等。
// 该方法用于两个相同数据类型的比较,两个不同类型的数据不能用此方法来比较。
Integer x = 5;
System.out.println(x.compareTo(3)); //1
System.out.println(x.compareTo(5)); //0
//2、equals:判断number对象是否与参数相等。
int y = 10;
System.out.println(x.equals(y)); //false
//3、toString:以字符串形式返回值
System.out.println(x.toString()); //“5”
System.out.println(Integer.toString(12)); //"12"
//4、parseInt、parseDouble:将字符串解析为int double类型。
int x1 =Integer.parseInt("9"); //9
double c = Double.parseDouble("5"); //5.0
System.out.println(x1+c);
//5、0-1随机数
System.out.println(Math.random());
//6、[0,99]的随机数random.nextInt(100):
[1,100]的随机数random.nextInt(100)+1:
//7、[10,20]生成十个制定范围的整数
final int START=10;
final int END=20;
for (int i=0;i<10;i++) {
int number=random.nextInt(END-START+1)+START;
System.out.printf(" %d ",number);
}
System.out.println(Math.abs(-1.1));
System.out.println(Math.ceil(1.1));
System.out.println(Math.floor(-1.1));
System.out.println(Math.round(-1.1));
2. Java数组
2.1 Java 数组的定义
1. 数组是用来存储固定大小的同类型元素
//PS:不确定数组元素内容使用动态初始化,确定数组元素内容使用静态初始化
//一维数组静态初始化:指定内容,但数组自动推导数组长度
//标准格式:数据类型[] 数组名称=new 数据类型[]{1,2,3}
int[] arrA=new int[]{1,2,3};
String[] arrB=new String[]{"abc","aaa"};
//省略格式:数据类型[] 数组名称={1,2,3}
int[] arrC={1,23,3};
char[] arrD={'A','B'};
//一维数组动态初始化:指定长度
//标准格式:数据类型[] 数组名称=new 数据类型[数组长度]
int[] arrayA=new int[10];
double[] arrayB=new double[10];
String[] arrayC=new String[10];
//二维数组静态初始化:指定内容
//标准格式:数据类型[][] 数组名称=new 数据类型[][]{{1,2,3},{12},{1,3}}
int[][] arrAA=new int[][]{{1,2,3},{12},{1,3}};
//省略格式:数据类型[] 数组名称={1,2,3}
int[][] arrBB={{1,2,3},{12},{1,3}};
//二维数组动态初始化:指定长度
//标准格式:数据类型[][] 数组名称=new 数据类型[数组长度][]
int[][] arrayCC=new int[10][10];
2. 数组的优势与局限
可以方便的表示大量具有相同数据类型的元素
数组一旦创建,长度就不能改变,不存在动态增加的数组,但是有集合,可以动态的增加内容
3. 数组的遍历访问(普通循环,增强for循环)
for (int i=0;i<array.length ;i++ ) {
System.out.printf("%d ",array[i]);
}
for(int elment:array1){
System.out.printf("%d ",element);
}
2.2 数组顺序查找
import java.io.*;
import java.util.*;
public class test{
public static void main(String []args){
int[] arr={2,4,1,3,43,23};
System.out.println("请输入您要查找的数值!");
Scanner sc=new Scanner(System.in);
int number=sc.nextInt();
for (int i=0;i<arr.length;i++){
if (number==arr[i]) {
System.out.printf("已经查找的数值:%d ",arr[i]);
break;
}
}
}
}
2.3 数组冒泡排序
public class test{
public static void main(String []args){
int[] arr={2,4,1,3,43,23};
for (int i=0;i<arr.length;i++){
for (int j=0;j<arr.length-i-1;j++) {
if (arr[j]>arr[j+1]) {
int temp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
for (int element:arr) {
System.out.println(element);
}
}
}
2.4 Arrays工具类的使用
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
具有以下功能:
int[] array={1,4,2,44,23,24};
//1、整型数组转为字符串
String s=Arrays.toString(array);
System.out.println("s:"+s);
//2、对数组array进行排序
Arrays.sort(array);
for (int i=0;i<array.length ;i++ ) {
System.out.printf(" %d ",array[i]);
}
//3、对数组进行二叉查找
int n=Arrays.binarySearch(array,44);
System.out.println("\n 44的下标:"+n);
//4、判断两个数组内容、顺序是否一致
int[] array2={1,4,2,44,23,24};
boolean b=array.equals(array2);
System.out.println("array,array2两个数组内容、顺序是否一致:"+b);
3. Java面向对象
3.1 简介
1. 面向对象的封装特性
/Users/zhupeng/Desktop/Java/DemoCode/基础代码/demo04Class.java
1.1类中成员变量、成员方法的定义
public String s;
public void method(){
方法体;
}
1.2构造方法的定义和调用
定义:
public ClassName(){
初始化赋值
}
构造方法的作用:
1、能使一个对象在被创建的时候就完成了所有的初始化的工作。如果省略构造方法,能正确执行,Java编译器会自动为该类生成一个默认的构造方法,程序在创建对象会自动调用默认的构造方法。
2、本类方法调用构造方法this(),不可以用ClassName()
子类方法调用父类构造方法super()
3、this、super必须放在方法第一行,
this、super不能同时使用
this、super不能在static方法内调用
1.3局部变量和成员变量的作用域问题:
局部变量的作用域在于下一个”}”出现之前,其它方法类或外部无法访问。
成员变量的作用域取决于public(本类方法、外部、包内、继承类可访问) private (本类方法可访问、外部和包内和继承类不可访问)default (本类方法、外部、包内可访问)
1.4静态属性、静态方法、静态代码块:
public static String num=“朱鹏”;
public static void staticMethod(){
//方法体
}
静态属性、静态方法都属于类,所以对象共享,推荐使用类名.静态属性、类名.静态方法名()进行访问,也可以对象.静态属性
1.5静态变量与实例变量有什么不同?
静态变量不需要实例化就可以使用,也可以通过实例对象来访问静态变量,
而实例变量需要实例化才能够使用。
静态方法可以访问本类或其他类的静态方法、静态变量,不能访问普通成员方法,成员变量
成员方法可以访问本类或其他类的静态方法、静态变量,可以访问普通成员方法,成员变量
3.2 继承
2.1、继承中构造方法的细节: 无返回值、方法名==类名、可以重载
public Teacher(){
//super();默认调用父类构造
System.out.println("子类无参构造方法");
}
public Teacher(int n){
super(n);
System.out.println("子类有参构造方法"+n);
}
2.2、方法的重写与方法的重载有何不同?
1、方法的重写是子类和父类之间的关系,是垂直关系;
方法的重载是同一个类中方法之间的关系,是水平关系。
2、 重写只能由一个方法,或只能由一对方法产生关系;方法的重载是多个方法之间的关系。
3、重写要求参数列表相同;重载要求参数列表不同。
4、重写关系中,调用那个方法体,是根据对象的类型(对象对应存储空间类型)来决定;重载关系,是根据调用时的实参表与形参表来选择方法体的。
2.3 this和super分别有什么特殊的含义?
super( ):是从子类的构造方法调用父类的构造方法。
this( ):则是在同一类内调用其他构造方法。
3.3 多态
3.1什么是多态机制?Java语言中是如何实现多态的?
多态是指一个对象拥有多种状态,父类引用指向子类对象(子类对象就当作父类对象),通过指向父类的对象,来调用在不同子类中的成员函数(接口与此类似)
继承extends与接口implements是多态性的前提
实现方法:
父类名 对象名 = new 子类();
接口名 对象名 = new 实现类();
//容易出错!!
3.2、对象的向上转型(多态)
含义:创建一个子类对象当作父类使用 一定安全
格式:父类名称 对象名=new 子类名称
Fu obj=new Zi();
成员方法:父类特有方法、父子类重载方法
成员方法调用规则:
若子类对父类方法重写了,则调用子类方法(父类方法被覆盖)
若子类没有对父类方法重写,则调用父类方法
此时obj指向父类,不能调用子类独有的方法
成员变量调用规则:
对象名.成员方法(优先子类):同上面成员方法调用规则
3.3、对象的向下转型(多态):进行还原(调用子类特有方法)
格式:子类名称 对象名=(子类名称)父类对象
Zi zi=(Zi)obj;
3.4 抽象
4.1抽象方法与抽象类定义
抽象类:当父类中某个成员函数不能确定其准确的功能且明确的知道子类会调用这些方法时,则需要使用抽象类
抽象方法:是没有实现方法体的方法,而是要保留给抽象类派生出的子类来定义。
abstract class Animal{
abstract public void eat();
abstract public void drink();
}
注意:
(1)抽象类可以继承
(2)当一个类继承的父类为抽象类的话,则需要把抽象类中的所有抽象成员函数全部实现
(3)抽象类不能实例化一个对象
错:Animal an=new Animal()
(4)抽象类可以没有抽象方法(成员函数)
(5)抽象成员函数不能实现
(6)抽象类不一定包含抽象方法
抽象方法一定属于抽象类
3.5 接口与抽象类
1. 什么是接口?为什么要定义接口?
Java接口是一系列方法的声明,是一些方法特征的集合。
定义接口的原因:当一个类实现一个接口时,它必须实现接口中定义的所有方法
使用interface来定义一个接口。接口定义与类的定义相同,拥有成员变量和成员方法,但是成员变量必须是静态的,而且一定要赋初值,而且之后不能再修改,其成员方法必须是抽象方法。
2. 接口与抽象类有两点不同:
(1)接口的数据成员都是静态的且必须初始化;
(2)接口中的方法必须全部声明为abstract。
4. 异常
1、什么是异常?简述Java语言的异常处理机制。
异常是指在程序运行中由代码产生的一种错误。
处理机制:1.异常 2.抛出异常 3.捕获异常
1.在发生异常的地方直接处理 throw
2.将异常抛给调用者,让调用者处理 throws
2、异常的分类
2.1.检查性异常(编译异常)java.lang.Exception
定义:程序正确,但因为外在的环境条件不满足引发(不是程序本身的逻辑错误,而很可能是远程机器名字错误(用户拼写错误)),对于商用软件系统,必须考虑这个问题,JAVA编译器强制要求处理这类异常,如果不捕获这类异常,程序将无法编译。
例如,用户错误及I/O问题,打开不存在的文件
2.2.运行期异常 java.lang.RuntimeException
定义:程序存在逻辑错误(BUG),这类异常需要更改程序来避免,JAVA编译器要求强制处理这类异常
例如:数组越界,0做除数,入参不规范
2.3.错误 java.lang.Error
定义:一般很少见,也很难通过程序来解决,它可能源于程序的Bug,但一般更可能源于环境问题,入内存耗尽,错误在程序无需处理,而由运行环境处理
3、异常处理
3.1、throw关键字:在指定的方法中抛出指定的昇常
使用格式:
throw new xxxException( "昇常声生的原因“);
注意:
1. throw关键字必须写在方法的内部
2. throw关键字后边new的対象必须是Exception或者Exception的异常对象
3. throw关键字抛出指定的异常対象,必须处理这个异常
throw关键字后边创建的是RuntimeException或者是RuntimeException的子类対象,我可以不处理,默认交给JVM
3.2、throws关键字:异常处理的第一种方式,交给别人处理
作用:
1、当方法内部抛出异常对象的时候,那么我们就必须处理这个异常对象
2、可以使用throws关键字处理异常对象,会把异常对象声明抛出给方法的调用者处理(自己不处理,给别人处理),最终交给JVM处理-->中断处理
使用格式:在方法声明时使用
修饰符 返回值类型方法名(参数列表) throws AAAExcepiton, BBExcepiton...{
throw new AAAExcepiton("产生原因");
throw new BBBExcepiton(”产生原因");
}
注意:
1. throws关键字必须写在方法声明处
2. throws关键字后边声明的异常必须是Exception或者是Exception的子类
3. 方法内部如果抛出了多个异常对象,那么throws后边必须也声明多个异常
如果抛出的多个异常对象有子父类关系,那么直接声明父类异常即可
4. 调用了一个声明抛出异常的方法,我们就必须的处理声明的异常
要么继续使用throws声明抛出,交给方法的调用者处理,最终交给JVM
要么try...catch自己处理异常
3.3、try...catch:异常处理的第二种方式,自己处理异常
格式:
try{
可能产生异常的代码
}catch(异常变量){
一般在工作中,会把异常的信息记录到一个日志中
}catch(异常变量){
//这个语句块,不管有没有异常,都会执行
//一般用于资源释放
}
注意:
1.try中可能会抛出多个异常対象,那幺就可以使用多个catch来处理异常対象
2.如果try中发生了昇常,那幺就会执行catch中的异常处理逻辑,并继续执行try...catch之后的代码
如果try中没有发生了昇常,就不会抉行catch中异常处理逻辑
以下情形finally不会被执行:
(1)finally块发生异常
(2)程序所在线程死亡
(3)在前面的代码中使用System.exit();
(4)关闭CPU
4、系统定义的异常与用户自定义的异常有何不同?如何使用这两类异常?
系统定义的异常主要用来处理系统可以预见的较常见的运行时异常,对于某个应用程序特有的运行时异常,则需要自己创建用户自定义的异常类和异常对象。
5、运行和编译异常区别
Throwable是所有异常和错误的父类:
Exception:编译期异常,写java代码出现出错
RuntimeException:运行期异常,比较难排出
CompilerException:编译异常
Error:错误,非常难排出OOM
5. 范型
范型(模板):
(1)基本概念:范型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,
这种参数可以在类,接口和方法的创建中,分别称为范型类,范型接口,范型方法
(2)优点:
1.在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,
2.提高代码的重用率(安全 简单)
3.其反射机制很有用
(a)得到T的类型名称
变量a.getClass.getName()
(b)得到范型T内的各个成员函数名
Method m[]=a.getClass.getDeclareMethods();
for(int i=0;i<m.length;i++){
System.out.println(m[i].getName());
}
范型通配符:?不能创建对象使用,只能作为参数
范型优点:
(1)类型安全(2)向后兼容(3)层次清晰(4)性能较高
(5)通过反射机制可以取出函数名,函数类型,函数参数
6. IO流
1、InputStream、OutpuStream、Reader和Writer四个类在功能上在功能上有何异同?
InputStream和OutputStream类及其子类既可用于处理文本文件也可用于处理二进制文件,但主要以处理二进制文件为主。
Reader和Writer类可以用来处理文本文件的读取和写入操作,通常是以它们的派生类来创建实体对象,再利用它们来处理文本文件读写操作。
2、File类的作用
文件:是数据源的一种,保存数据的地方 Word文件 Excel文件
文件在程序中是以流的形式来操作的
3、File类中常用方法的使用介绍
总结文件类重要函数:
1、获取功能的方法
f.getAbsolutePath() //得到文件路径
f.getPath() //传递的路径名
f.length()) //得到文件大小
f.getName() //文件名
2、判断功能的方法
f.exists() //判断文件存在
f.isDirectory() //判断文件夹是否存在
f.isFile() //判断文件是否存在
3、创建、删除功能的方法
f.createNewFile(); //创建文件
f.mkdir(); //不存在,可以创建文件夹
f.mkdirs(); //不存在,可以创建多级文件夹
f.delete(); //删除文件或者文件夹
4、其它功能方法
f.listFiles(); //读取文件夹下的文件,返回类型为File数组
f.list();
fos.write(s.getBytes()); //a按字节写入fos中
fis.read(bytes))//按字节将fis内容写入数组bytes
4、IO流的概念和工作原理
流:数据在文件与内存之间的
输入流:数据从文件向内存流动(流向内存)FileInputStream FileReader
输出流:数据从内存向文件流动(流出内存)FileOutputStream FileWriter
5、IO流的分类
Java流分为两种 输入 输出
字节流:用于读写二进制文件以及任何类型文件InputStream Outputstream
字符流:用于读写文本文件,不能操作二进制文件 Reader Writer
6、文件流的使用
FileOutputStream:文件字节输出流
作用:把内存中的数据写入到硬盘的文件中
构造方法:
FileOutputstream(String name,boolean append ) 创建一个向具有指定 名称的文件中写入数据的输出文件流。
FileOutputstream(File file,boolean append) 创建一个向指定File 对象表示的文件中写入数据的文件输出流。
FileInputStream:文件字节输入流、把硬盘文件中的数据,读取到内存中使用
构造方法:
FileInputStream(String name )
FileInputStream(File file)
参数:读取文件的数据源
String name :文件的路径
File file:文件
7、文件字符流的使用
FileReader:文件字符输入流:把硬盘文件中的数据以字符的方式读取到内存中
构造方法:
FileReader(String fileName )
FileReader(File file)
参数:读取文件的数据源
String fileName :文件的路径
File file:一个文件
Filewriter:文件字符输出流 把内存文件中的数据以字符的方式读取到硬盘中
构造方法:
Filewriter(File file)
Filewriter(String fileName)
8、缓冲流的使用
BufferedInputstream BufferOutputStream:字节缓冲输入、输出流
BufferedReader BufferedWriter:字符缓冲输入、输出流
7. 多线程
7.1 进程和线程的介绍
●进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程
●线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
简而言之:一个程序运行后至少有一个进程, -一个进程中可以包含多个线程
多线程的优势
1、进程之间无法共享数据,线程直接可以共享
2、线程创建的代价较小,不必再次分配资源
3、Java语言内置了多线程功能支持,简化了java多线程编程。
7.2 线程三态转化
1、新建状态:用new关键字和Thread类或其子类创建后,该线程处于新建状态。处于新建状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)
PS:不能对已经启动的线程再次调用start方法,编译报错 Java.lang.IllegalThreadStateException异常
2、就绪状态:处于就绪状态的线程已经具备了运行条件,等待系统为其分配CPU。但是等待状态并不是执行状态
PS:如果希望子线程调用start()方法后立即执行,可以使用Thread.sleep()方式使主线程睡眠一伙儿,转去执行子线程。
3、运行状态:处于就绪状态的线程,如果获得了cpu的调度,就会从就绪状态变为运行状态,执行run()方法中的任务。如果该线程失去了cpu资源,就会又从运行状态变为就绪状态。重新等待系统分配资源。也可以对在运行状态的线程调用yield()方法,它就会让出cpu资源,再次变为就绪状态。
4、阻塞状态:处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。
5、死亡状态:当线程的run()方法执行完,或者被强制性地终止,就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。 如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
7.3 创建线程和启动
A、继承自Thread类
B、实现Runnable接口
7.4 线程管理
1、sleep()—线程睡眠:使当前执行线程暂停工作(线程停止但不释放锁),以指定毫秒数加上指定的纳秒数,以系统定时器和调度器的精度和准确性为准。sleep是静态方法,最好不要用Thread的实例对象调用它。sleep方法比yield方法有更好的可移植性,通常不要依靠yield方法来控制并发线程的执行。(运行阻塞)
2、yield()—线程让步: 与sleep()方法有点相似,它也是Thread类提供的一个静态的方法,使当前正在执行的线程暂停(线程停止但不释放锁),让同优先级的线程继续执行(高风亮节)。但是和sleep()方法不同的是,它不会进入到阻塞状态,而是进入到就绪状态。(运行就绪)
3、join()—线程合并:线程的合并的含义就是将几个并行线程的线程合并为一个单线程执行,应用场景是当一个线程必须等待另一个线程执行完毕才能执行时(释放锁),Thread类提供了join方法来完成这个功能,注意,它不是静态方法。
4、synchronized()—线程同步:是同步代码块加锁解锁用的, 同步锁被synchronized修饰的方法或者代码块,同一时刻只允许被一个线程访问(线程停止但不释放锁)
5、volatile—线程同步:volatile关键字为域变量的访问提供了一种免锁机制;使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新。volatile不会提供任何原子操作,它也不能用来修饰final类型的变量。
private volatile int account = 100;
6、wait()—线程通信:线程释放CPU的所有权(释放锁),并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象的监视器的线程醒来(运行阻塞)
7、notify()—线程通信:唤醒下一个线程
8、notifyAll()—线程通信:唤醒所有线程
7.5 线程池
合理利用线程池能够带来三个好处。
1、降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
2、提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
3、提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
8. 反射
反射:框架设计的灵魂
*框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
*反射:通过加载类字节码的方式来获取相关类的一些信息 比如成员变量,成员方法等
好处:
1.可以在程序运行过程中,操作这些对象。
2.可以解耦,提高程序的可扩展性。
*获取class对象的方式:
1.Class.forName("包名.全类名") :将字节码文件加载进内存,返回class対象
多用于配置文件,将类名定义在配置文件中,读取文件,加载类
2.类名.class :通过类名的属性class获取
多用于参数的传递
3.对象.getclass(): getclass()方法在object类中定义着
多用于对象的获取字节码文件
结论:同一个字节码文件在一次程序运行过程中,只会被加载一次,不论通过哪一种
方式获取的Class对象都是同一个
Class对象常用方法:
获取功能:
1.获取成员变量
* Field[] getFields() :获取public修饰的成员变量
* Field getField(String name) :获取public修饰的指定成员变量
* Field[] getDeclaredFields() :获取所有的成员变量
* Field getDeclaredField(string name):获取指定的成员变量
Field:成员变量
1.设置值:void set(Object obj, object value)
2.获取值:get(object obj)
3.忽略访问权限修饰符的安全检查:setAccessible(true):暴力反射
2.获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>... parameterTypes)
* Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
* Constructor<?>[] getDeclaredConstructors()
Constructor:构造方法
创建对象:T newInstancel(object... initargs)
3.忽略访问权限修饰符的安全检查:setAccessible(true):暴力反射
3.获取成员方法们:
* Method[] getMethods()
* Method s(String name, 类<?>... parameterTypes)
* Method[] getDeclaredMethods()
* Method getDeclaredMethod(String name,类<?>... parameterTypes)
4.获取类名
* String getName()