Java
java基础
java是一门跨平台的语言:一次编写,处处运行
java能够跨平台的原因,是因为有各种类型的jvm,且各个jvm不跨平台
java开发:写代码(java)——>编译(class)——>执行(class)
jvm:java虚拟机
jre:jvm+核心类库:只能运行java程序,但不能开发(写代码)
jdk: jre+运行环境工具:既能运行,也能开发
jvm<jre<jdk
安装jdk
配置环境变量
- path(必须):安装jdk的根目录\bin
- classpath:安装jdk的根目录\lib
- java_home:安装jdk的根目录
验证:cmd(win+r) ,输入java -version
程序详解
class 后面的是类名
每个java文件可以有多个类class ,但只能有一个public class(公共类)
转义符 \
\n 换行
\t 制表符 (Tab)补满一定位数
编码问题
java默认编码集是unicode
注释
单行 //
多行 /* */
文档注释 /** */
Eclipse
提示/自动补全: Alt+/
Idea
自动补全 : Tab
main方法: psvm+Tab
输出:sout+Tab
提示: Alt+回车
Ctrl+P:查看方法参数
变量
变量存在于内存中(程序结束,计算机关机后,变量失效)
变量:1.声明数据类型(整数,小数,字符串…) 2.赋值 3.使用
变量名不能重复
变量名区分大小写
局部变量使用之前必须赋初值
变量的有效范围:最近的一对{}
java数据类型
原生数据类型(基本数据类型)8个
数字
整数byte<short<int<long 默认int
小数float<double 默认double
非数字
字符char 只能放一个字符,并且需要用单引号引起来
布尔boolean :只有true/false
整数<小数<字符串
引用数据类型(对象类型)
String 字符串
变量应用
java可以直接表示的进制
二进制 :0b数字
十进制
八进制:0数字
十六进制:0x数字
从控制台输入Scanner
Scanner 中有很多类型的输入方法,但没有输入字符char的方法
Scanner input = new Scanner(System.in);
int num = input.nextInt();
System.out.println(num);
输入字符串的方法:String name = input.next();//输入字符串
String name = input.nextLine();//输入字符串
nextLine()与next()的区别:
next():不接收空格,回车,并将空格,回车作为终止符
nextLine():接收空格,回车
数据类型的转换
自动转换
范围小的类型可以自动转化为范围大的类型
范围小的类型遇到范围大的类型,自动转换为范围大的类型
整数<小数<字符串,任何类型遇到字符串,自动转换为字符串
char<int
强制转换
范围大的赋值给范围小的,必须强转
通用写法: int num = (int)1.2; 范围小的 = (小类型)范围大的
特殊写法:float f = 123.4f;
算术运算符
+加号 /连接
—减号
*乘法
/除法
%求余,结果永远与被除数一致
关系运算符(比较运算符)
大于>
小于<
大于等于 >=
小于等于 <=
等于 ==
不等于 !=
字符串比较 equals() !equals()
运算结果全是布尔值
位运算
效率最高
逻辑运算符
非,不等于 !
且 &&
或 ||
i++ 先用后加
++i 先加后用
三目运算符
布尔判断?a:b
如果true返回a,如果false返回b
小数运算可能遇到的问题
System.out.println(3*0.3);//的结果是0.8999999999999999
int的范围能够容纳下2的32次方个数字,float/double是小数,无穷无尽个数字,因此2的32 个位置无法容纳所有小数
选择结构
if
if(布尔条件){
…//如果条件为真则执行
}
if后面如果只有一条语句,则{}可以省略,如果有多条语句,则不可以省
if…else…
java语言的if(表达式),表达式必须是boolean类型
if(布尔条件){
…//如果条件为真则执行
}else{
…//如果条件为假则执行
}
简单的if…else…赋值语句可以等价为三目运算符
多重if:多重选择
if(布尔条件){
…
}else if(布尔条件){
…
} else{
…
}
嵌套if
if(){
if(){
}
}else{
}
如果使同一件事情用多重if,如果不是同一件事情,用嵌套if
switch选择
switch(表达式){
case 值:
…
break;//整个switch全部结束
case 值:
…
break;
default://都不匹配
…
}
switch会用表达式和所有的case匹配,如果匹配成功,则执行响应case后的语句,如果所有匹配都不成功则执行default后的语句
switch后支持的表达式类型:int ,short,byte,char,String,枚举
case后面的值必须是常量,且case值不能重复
default可以省略
switch只有遇到break或最后的}才会结束,否则都不结束
如果判断的是区间值用多重if,如果是离散值,用switch,多重if都可
随机数
Math.random();//产生[0,1)之间的随机数
产生n位随机整数:(int)(Math.random()*n位数最大值+1-n位数的最小值)+n位数的最小值;
循环
重复执行的事情
循环 = 循环条件 + 循环操作
while循环
先判断在执行
while(循环条件){
循环操作;
}
循环要注意更新变量,防止死循环(无限循环)
do…while
先执行后判断
do{
循环操作;
}while(循环条件);
do…while至少执行一次
for循环
while的变形
for(初始值;循环条件;更新变量){
循环操作
}
适合循环次数已知,或者始末条件已知
break退出循环
退出循环,终止循环
仅仅对当前层次的循环有效
continue跳过当前循环
跳过当前循环
仅仅对当前层次的循环有效
二重循环
循环里边套循环
while(){
while(){
}
}
外层循环执行一次,内层循环执行一轮
foreach
for(元素类型 变量名:数组){
…
}
数组
定义整数数组: int[] students = new int[300];
数据类型[] 数组名 = new 数据类型[数组长度];
数组的使用: 数组名[下标]——>数组元素
数组四要素: 数组名,下标,类型,数组元素
什么时候使用数组?: 当多个元素类型一致时,考虑用数组
数组定义有三种形式
int[] students = new int[3];只声明数组的元素个数,但不赋值(默认值)
int[] students2 = new int[]{1,2,3};只赋值,但不声明元素个数
int[] students3 = {1,2,3};理解为只赋值的简化形式,不能拆开写
数组长度: students.length
数组的最后一个元素下标 : students.length-1
对数组进行升序排序: Arrays.sort(numbers);
冒泡排序
总结:几轮? 元素个数-1
使用双重循环,外层几轮,内层两两元素比较
int[] numbers = new int[]{8,5,2,1,23,344,12};
for (int i=0;i<numbers.length-1;i++){for (int j=0;j<numbers.length-1-i;j++){if(numbers[j]>numbers[j+1]){int temp = numbers[j];numbers[j]= numbers[j+1];numbers[j+1] = temp;}}
}
for(int i=0;i<numbers.length;i++){System.out.print(numbers[i]+"\t");
}
二维数组
String[][] citys = {{…},{…},{…}} ;
类和对象
面向过程:将每一个过程全部写明白
面向对象:只需要写事情的目标即可
在面向对象编程中,将具体的成为对象(张三),将抽象的成为类(人)
多个对象可以抽象出类,类可以产生多个对象
类和对象的组成部分:
静态:属性(名值对——属性名,属性值)——身高,体重
动态(功能):方法——吃饭,睡觉
类可以细分,但细分的产物并不一定是对象。例如,人可以分为男人,女人
类:由一组抽象的属性,方法构成;对象:由一组特定的属性,方法构成。
Person zs = new Person();一般而言,栈里边的zs是引用,对象是指堆中的东西
栈里边存放基本类型,引用类型,方法,堆里边放的是实例对象
引用:相当于C语言中的指针,持有对象的内存地址
对象之间的直接赋值,赋值的是内存地址
语法:
创建类:public class Person(){
…}
对象使用前必须实例化(new)
创建类的对象: 类 对象 = new 类();
调用类中的属性和方法: 对象.属性 对象.方法
方法是多个对象共享的,属性是各个对象独有的
属性就是全局变量。全局变量:方法以外,类以内(有初始值,数据类型的默认值)
局部变量:方法以内(没有初始值,在使用前必须赋初始值)
局部变量可以和全局变量重名,并且局部变量优先级高
方法调用的常见情况:
同一个类中
都有static,都没static或者没的调有的,则可以直接调用
有static的不能直接调没static的方法
不在同一个类中
万能方法: 先new 对象 然后 对象.方法
如果调用的方法是static静态的方法,可以直接类名.方法
//静态方法
public static void play(){}
//非静态方法
public void play(){}
static方法是类级别的,属于类
非static方法是对象级别的,属于对象
类有的,对象自然有;对象有的,类不一定有
方法:
- 有返回值
public 返回值类型 方法名(){
return 类型对应的数据;
}
在调用有返回值的方法时,需要接收
-
无返回值(返回值位void)
-
有参数
个性
参数越多越个性化
public void sleep(参数列表){} //参数列表必须满足:类型,个数,顺序完全一致 public void sleep(String name){}public void sleep(String name,String place){} //多个元素类型相同--数组public void sleep(String[] names){} //多个元素类型不同--类/对象public void sleep(People people){} -
无参数
共性
对象数组
类型[] 数组名 = new 类型[];
缺点
数组长度固定,不可改变
数组无法求出真实有效数据的个数
用数组实现对象的增删改查操作比较麻烦
字符串
定义字符串方式
String a = “abc”;
String a1 = new String(“abc”);
String a2 = new String();//默认生成的使""
通用的理论:对于非基本类型(对象类型/引用类型)
1.只定义,不new,默认都是null
2.new实例化,就是“空”(数据类型的默认值)
==判断内存地址
任何类型遇到字符串,转为字符串
String是final类型的,一旦定义不可改变,如果在方法中对其修改,只是在堆中新开辟了一个空间,存放新值
常见的String方法
//判断两个字符串内容是否相等,返回值是boolean值,区分大小写,==判断内存地址
boolean result = a.equals("abc");//判断两个字符串内容是否相等,返回值是boolean值,不区分大小写
boolean result = a.equalsIgnoreCase("ABC");//字符串的长度,返回值是int类型
int length = a.length();//将小写转化成大写,返回值是String类型
String b = a.toUpperCase();//将大写转化成小写,返回值是String类型
String b = a.toLowerCase();//判断b是否存在与字符串a中,如果存在,返回值是b所在的位数,如果不存在,返回-1
int c = a.indexOf("b");//倒着查找
int b1 = a.lastIndexOf("c");//去掉首尾的空格,返回值是String类型
String trim = a.trim();//截取字符串,从start截取到end,start能取到,end取不到,返回值是String类型
String a = phone.substring(start,end);//截取字符串,从start截取,返回值是String类型
String a = phone.substring(start);//字符串拆分 split(),根据-分隔开字符串,返回字符串的数组,特殊符号不适用:. | \ $ + *且拆分符如果在末尾,则末尾字符无法被统计
String[] splits = a.split("-");//万能的字符串拆分
String str = "hello|world";
StringTokenizer token = new StringTokenizer(str,"|");
while (token.hasMoreTokens()){System.out.println(token.nextToken());
}//根据位置找字符,返回值时字符类型
char c = str.charAt(2);//replace,替换
String str = str.replace("老字符", "新字符");
StringBuffer类
String的增强版,比String最大的升级,可以在原来的内存空间中直接修改变量值
StringBuffer不是final类型的
如果对字符串需要频繁的修改,则不建议使用String类,而是使用StringBuffer类
//赋初始值
StringBuffer sb = new StringBuffer("abc");//字符串拼接,往最后拼接
sb.append("aaa");//字符串插入,往第二个位置插入bbb
sb.insert(2,"bbb");//倒序
sb.reverse();
StringBuffer与String之间各自独立,他们之间可以相互转换
//String ---> StringBuffer
String a = "abc";
StringBuffer a1 = new StringBuffer(a);//StringBuffer ---> String
String s = sb.toString();
String a2 = sb+"";//任何类型遇到字符串转为字符串
字符串常量池
使用字符串时,现在常量池中寻找,如果有,则使用,如果没有,则创建后放入常量池,并使用
new就是在堆中开辟空间,产生对象
字符串,如果直接使用字面量String str = “abc”;则从常量池中找,如果使用的时new,则从堆中找(而堆又会从常量池中查找,如果常量池没有,则在常量池中创建,并使用,就是引用常量池中的内存地址)
如果new之后,仍想从常量池中获取,则需要使用intern()方法
包package
作用和文件夹/目录的作用一摸一样
1.将类等资源进行结构化存储
2.防止重名问题
打包:package MyPackage; 如果多个类在同一个包中,通过package打包
导包:import com.Person; 如果多个类不在同一个包中,并且需要相互调用,就需要导包
访问修饰符
一般建议对属性/方法添加访问修饰符
private 私有的,只有当前类能够访问;其他类不能直接访问,如果要访问,需要借助于访问器:setter ,getter private和set,get方法配套使用
//this 代表当前类的属性
this.name = name;
public :全部可以访问
一般属性全是private ,方法全是public
继承重载重写与this和super
继承extends
多个类(子类)有多个相同的属性和方法,可以相同的属性和方法提出来放在一个单独的类里(父类)
作用:减少代码冗余
注意:如果一个方法,方法名相同,方法体不同,也不能提取到父类;只有完全相同的属性和方法才能提取到父类
子类继承父类中:private,构造方法无法被继承,但是子类可以显示的调用父类的构造方法(super)
重写
子类重写父类的方法
父类中已经存在a()方法,子类中又重新写了一个a()方法
super直接去父类中寻找方法,跳过子类
this在当然类中查找,如果当前类没有,去父类中查找
方法名一致,参数列表相同
方法重载
方法名一致,参数列表不一致(类型不同,个数不同,顺序不同)
注意两点:1.与返回值无关 2.与参数名无关
构造方法
//无参构造方法
public 类名(){
}dog d= new dog();
作用:实例化(new),产生一个对象
含参构造的作用:一次性可以赋多个属性值
默认是无参构造方法dog()
如果类中没有任何构造方法,则系统自动提供一个无参构造方法;如果类中有构造方法,则系统不会提供无参构造方法
建议:如果给类中编写构造方法,则手动编写一个无参构造方法,防止报错
构造方法调用构造方法要用this(…),且this只能放第一行,多个构造方法之间不能循环调用;如果构造方法调用普通方法,可以直接调用
如果子类要调用父类的构造方法要用super(…),且super只能放第一行
this调本类构造,super调父类构造,this/super只能放在第一行
构造方法不能被重写
初始化顺序
new(Xxx)之前干了什么事情:
父类static
子类static
父类普通代码块
父类无参
子类普通代码块
子类无参
抽象类abstract
抽象方法:abstract,没有方法体
抽象方法必须包含在抽象类中
抽象类不能实例化(new),原因:抽象类中可能存在抽象方法,而抽象方法没有方法体
子类必须重写父类中的抽象方法
final
final修饰的类不能被继承
final修饰的方法不能被重写
final修饰的变量,属性不能被修改
多态
父类引用指向子类对象
//多态,小范围赋值给大范围,父类对象引用子类对象
Pet pet = new dog();
//父类 名字 = new 子类();
步骤:1.编写父类,2.编写子类,并且子类重写父类的方法,3.运行时,父类引用指向子类对象
多态的几种实现方法:
1.方法重载
2.方法重写
3.使用父类作为方法的形参
4.使用父类作为方法的返回值
多态时:父类和子类之间的转换
1.从小到大,自动转换(double = int)
Pet dog = new Dog();
2.从大到小,强制转换(int = (int)double)
Dog dog = (Dog)(new Pet());
对象 instanceof 类型 :判断对象是什么类型,返回值是true或者false
接口
class 普通类 底层员工
abstract class 抽象类 中层
interface 接口 高层
接口里边的方法全部是抽象方法
public interface Person{//属性全部都是static final类型//全部都是抽象方法,默认全部都是public abstractpublic abstract void eat();
}
抽象方法相当于一种约定,能力 : 门(类)有锁(接口)的能力
接口和抽象类一样不能实例化(new)
实现类必须实现接口中的所有抽象方法
如果既有继承又有接口,必须先继承后实现接口
!!!!!!java类中单继承,但可以实现多个接口
接口注意事项:接口之间可以相互继承,多继承
接口也可以实现多态
接口中不存在构造方法
java值传递
java只有值传递
如果将a()方法中的基本类型变量x传入到b()方法中,并且在b()方法中对x进行了修改,则a()方法中的x变量值保持不变
如果将a()方法中的引用类型变量x传入到b()方法中,并且在b()方法中对x进行了修改,则a()方法中的x变量值与b()方法中保持一致
JDK8
lambda表达式
简化代码
lambda ( λ)的组成结构:
- 逗号隔开的参数列表(x,x,x) ()
- 箭头符号 ->
- 方法体( λ代码块)
lambda语法上要求重写的接口,抽象类中有且只能有一个抽象方法
lambda重写的接口,抽象类中会标识一个@FunctionalInterface,称之为函数式接口。
函数式接口:标注@FunctionalInterface,语法上要求有且只有一个抽象方法
lambda表达式重写的必须是函数式接口(或者只有一个抽象方法的抽象类)
函数式接口要注意以下几点
- 即使没有标注@FunctionalInterface,但是只有一个抽象方法,也称为函数式接口
- 特殊情况,如果某个接口中有多个抽象方法,但只有一个抽象方法是本接口新定义的,其他方法与Object中已有的抽象方法重复,那么该接口仍然是函数式接口
函数式接口从哪来?
-
JDK自带(很多存在与java,util.function包中)
四大核心函数式接口
- 有参,无返回值(消费型)
- 有参,有返回值(函数型)
- 无参,有返回值(供给型)
- 断言式接口(返回值是boolean)
-
自定义
lambda表达式的使用方式
方式一
函数式接口 引用名 = lambda表达式;
//抽象方法
int add(int num1,int num2);
//实现
public static void tets(){//lambda自带类型推断机制,因此参数的类型可以省略MyInterface mi = (n1,n2)->{return n1+n2;};System.out.println(mi.add(5,6));
}
方式二
将lambda表达式所代表的函数式接口,作为一个方法的参数存在
方法A(方法B):函数式编程。scala,javascript本身就支持函数式编程
public static void test2(){System.out.println(upper((x)->x.toUpperCase(),"hello"));
}public static String upper(Function<String,String> fun ,String str){return fun.apply(str);
}
JDK8的其他特性
接口的m默认方法与静态方法
方法引用
重复注解
其他
集合框架
对象数组的缺点
数组长度固定,不可改变
数组无法求出真实有效数据的个数
用数组实现对象的增删改查操作比较麻烦
因此提出集合
1.Collection的长度自动适应,不必人工干预
2.size(); 返回集合中真实数据的个数,int
3.用数组实现对象的增删改查很方便
集合 Collection是一个接口,一些 Collection允许由重复的元素,而另一些不允许,一些 Collection是有序的(输入顺序和输出顺序一致),而另一些是无序的
Collection:存储的数据是不唯一,无序的对象
List:存储的数据是不唯一,有序(输入顺序是否与输出顺序一致)的对象
Set:存储的数据是唯一(不能重复),无序的对象
Collection最常见的方法
add(Object e)像集合中增加一个元素
clear() 清空集合中的所有元素
size() 返回集合中真实数据的个数,返回类型为int
addAll(Collection c) 可以将一个集合中的全部元素,增加到另一个集合中
contains(Object e) 判断集合中是否包含指定元素,返回类型为boolean类型
containsAll(Collection c) 判断此集合中是否包含指定集合中的所有元素,返回类型为boolean类型
equals(Object e) 判断集合与指定对象是否相等 ,返回类型为boolean类型
isEmpty() 判断集合是否为空 ,返回类型为boolean类型,如果为空返回true,非空返回false
iterator()迭代器 ,迭代当前集合的每一个元素,返回值为迭代器类型
Iterator iterator = coll1.iterator();
//iterator.hasNext(); 判断集合是否有下一个元素
while (iterator.hasNext()){Object result = iterator.next();//取出下一个元素System.out.println(result);
}
remove(Object e) 从当前集合中删除指定的对象,如果存在的话
removeAll(Collection c) 从当前集合中删除指定集合中的所有元素
retainAll(Collection c) 与removeAll是相反操作,从当前集合中,只保留另一个集合中的元素
toArray() 将集合转换为数组,返回类型为Object[]
List常见方法
List是有序的
List有Collection中的所有方法,另外List有自己新增的方法
重载的 add(int index,Object element) 向集合中指定位置插入元素
重载的 addAll(int index,Collection c) 可以将一个集合中的全部元素,增加到另一个集合中的指定位置
get(int index) 返回列表中指定位置的元素,类似于数组的下标
indexOf(Object o) 返回集合中第一次出现指定元素的位置,如果此集合中不包含该元素,返回-1
lastIndexOf(Object o) 返回集合中最后一次出现指定元素的位置,如果此集合中不包含该元素,返回-1
remove(int index) 从当前集合中删除指定位置的对象,如果存在的话
set(int index,Object element) 用指定元素替换集合中指定位置的元素
subList(int index,int index) 截取集合 [) 左闭右开
ArrayList与LinkedList的区别
ArrayList是动态数组,数组长度“可变”,元素与元素之间是相邻的,查询比较方便,增删改比较麻烦
LinkedList(相当于链表) 增删改比较方便,查询比较麻烦
Map
Collection与Map之间相互独立
Collection:单值集合
Map:双值集合,“键值对”(key-value)集合,可以根据键找到值,kv之间一一对应
Map中key是唯一的,value不是唯一的
Map是无序的
Map常用的方法
put(key,value) 像map中增加对象
get(key) ,根据key获取value, 返回值为value
size(), 返回元素的个数
containsKey(key) 判断是否包含了指定的key
containsValue(value),判断是否包含了指定的value
keySet() 将Map转换为只包含key的单值集合,返回值为Set, 因为key是唯一的
values() 将Map转换为只包含value的单值集合,返回值为Collection
remove(key) 删除Map中的对象
删除:Collection中的类(List,Set),删除的返回值都是boolean值
Map中的类,是根据Key删除的,返回值是Value
如何遍历集合?
单值集合list,set
1.循环for(普通for[只适用于有序的集合];foreach,增强for[建议])
List list = new ArrayList();list.add("a");list.add("b");list.add("c");System.out.println(list);for (int i=0;i<list.size();i++){System.out.println(list.get(i));}//无序Set set = new HashSet();set.add("dd");set.add("ee");set.add("ff");for (Object a:set){System.out.println(a);}
2.迭代器
//迭代器
public interface Iterator<E>{...}boolean hasNext();//1.判断是否有下一个元素,true/false//2.如果又下一个元素,引用后移next();//取出当前元素//使用
Iterator iterator = set.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
多值集合Map
将双值集合砖和单值集合
HashMap map = new HashMap();
map.put("s01","zs");
map.put("s02","ls");
map.put("s03","ww");
Set set = map.keySet();
Collection values = map.values();
for(Object o:set){Object o1 = map.get(o);System.out.println(o+"\tvalue\t"+o1);
}
通过entry遍历
entry = key+value,一个entry就是一个键值对(kv对)
HashMap map = new HashMap();
map.put("s01","zs");
map.put("s02","ls");
map.put("s03","ww");
Set set = map.entrySet();
for (Object o:set){Map.Entry e1 = (Map.Entry)o;Object key = e1.getKey();Object value = e1.getValue();System.out.println("k:"+key+"\tvalue:"+value);
}
泛型
Collection ,Map接口中都可以使用
自JDK1.5开始提供
作用:
(1)数据安全
(2)防止类型转换时出错
list.add默认是Object类型,如果加了泛型,则自动变成list.add(泛型的类型),返回值类似,直接返回泛型类型
泛型只能是引用类型,不能是基本类型
例如
List<Double> list = new ArrayList<Double>();
list.add(2.4);
Double aDouble = list.get(0);
集合工具类
集合工具类Collections
//按字典顺序排序
Collections.sort(list);
System.out.println(list);//取最大值,最小值
System.out.println(Collections.max(list));
System.out.println(Collections.min(list));
数组工具类Arrays
比较器
Collections.sort() 只能够识别一些自然顺序
自定义比较器:Comparable , Comparator
Comparable:内部比较器(侵入性,需要修改原有代码)
在比较对象中实现Comparable接口,重写里边的compareTo()方法,在compareTo()方法中编写比较的逻辑,重点是返回值 -1,0,1
Comparator:外部比较器(无侵入性,不影响原有代码)
定义外部比较器,实现Comparator接口,重写里边的compare()方法,在compare()方法中编写比较的逻辑,重点是返回值 -1,0,1
包装类
自动装箱:基本类型—>包装类型
自动拆箱:包装类型—>基本类型
java中将8个基本类型,包装成8个对象类型(引用类型)。这8个对象类型,就称为包装类
异常
try{
一切正常,执行的代码
}catch(Exception e){
如果不正常,执行这里
}
如果代码出现问题时,使用“异常机制”比“选择结构”更加方便
异常的继承结构图
运行时异常:代码在编辑(编译阶段)时不报错,运行时才报错。语法上,可以选择性处理
检查异常:代码在编辑(编译阶段)时报错,在编辑时,必须处理
异常重点
try catch finally throws throw
处理异常 try catch 或者 throws
try catch
自己(当前方法)能够处理,使用try catch
try:将可能发生异常的代码用 {} 包裹起来
catch: 捕获特定类型的异常
如果try中的代码发生了异常,则程序不在执行try中异常之后的代码,而是直接跳到catch中的代码
throws
自己(当前方法)不能处理,上交给方法调用处处理,使用throws
finally
无论正常还是异常都会执行的代码
1.即使遇到return,也仍然会执行finally
2.除非虚拟机关闭,才不会执行finally
多个catch块
try{
}catch(){
}catch(){
}
先写范围小的类型,再写范围大的类型
throw
一般和自定义异常一起使用
jdk中自带了很多类型的异常,但如果这些内置异常仍不能满足项目的需求,那么就需要创建自定义异常
如何编写自定义异常
1.类继承子Exception,调用super(“异常信息”)
2.使用throw声明一个自定义异常,并进行try catch或throws
java注解
类:要给一个类增强一些功能,可以继承,实现一个接口,还可以使用注解
可以通过使用注解增强类,方法,属性的功能
内置注解
@Override:可以确保 重写的方法 的确存在于父类或接口中,可以有效的避免单词拼错
自定义注解
元注解
元数据:修饰数据的数据
元注解:修饰注解的注解
@Target : 限制注解能够使用在哪些元素上(属性,方法,类)
@Retention : 限制注解的生命周期
@Document
@Inherited
自定义注解什么时候使用? 一般结合反射使用,注解+反射一般在开发框架时使用
IO
I:InputStream 输入流
O:OutputStream 输出流
文件:硬盘上的文件 txt docx 电影,图片
通过IO操作文件
java.io.*
//file 可以代表一个不存在的文件File file = new File("F:\\前端 works\\html\\abc.txt");System.out.println("相对路径:"+file.getPath());System.out.println("绝对路径:"+file.getAbsolutePath());System.out.println("文件名:"+file.getName());// boolean flag = file.exists();
// try {
// if (!flag){
// file.createNewFile();
// System.out.println("创建成功");}
// else {
// file.delete();
// System.out.println("删除成功");
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
流
流是一种FIFO的数据结构 ,先入先出
分类
按流向(以内存为参照点)分类:
输入流 : java.io.InputStream 抽象类 /Reader
输出流 : java.io.OutputStream 抽象类 /Writer
按照处理单元
字节流: FileInputStream FileOutputStream ;字节流就是将文件内容转为了字节形式进行传输,1字节—>8bit(二进制),二进制可以传输任何类型的数据,因此字节流也可以传输任何类型的数据,字节流缓冲区使用的是byte[]
字符流: Reader Writer ;只用于处理字符,字符流缓冲区使用的是char[]
其他流
字节输入流
InputStream in = null;try {in = new FileInputStream("F:\\前端 works\\html\\abc.txt");byte[] buf = new byte[in.available()];//在内存中定义字节数组in.read(buf); //将文件中的内容存在字节数组中//将buf转成StringSystem.out.println(new String(buf));} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {in.close();} catch (IOException e) {e.printStackTrace();}}
字节输出流
OutputStream out = null;try {out = new FileOutputStream("F:\\前端 works\\html\\def.txt");out.write("Hello Word".getBytes());} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {out.close();} catch (IOException e) {e.printStackTrace();}}
字节流文件复制
//文件复制InputStream in = null;OutputStream out = null;//abc.txt -> 内存 -> xyz.txttry {in = new FileInputStream("F:\\前端 works\\html\\abc.txt");out = new FileOutputStream("F:\\前端 works\\html\\xyz.txt");//一次开辟10字节内存byte[] buf = new byte[10];int len = -1;while ((len=in.read(buf))!=-1){out.write(buf,0,len);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {if(out!=null) out.close();} catch (IOException e) {if(in!=null) e.printStackTrace();}try {in.close();} catch (IOException e) {e.printStackTrace();}}
字符流文件复制
Reader re = null;Writer wr = null;//文件到内存try {re = new FileReader("F:\\前端 works\\html\\abc.txt");char[] buf = new char[4];int len = -1;StringBuffer sb = new StringBuffer();while ((len = re.read(buf))!=-1){sb.append(buf,0,len);//将每次读取到的数据存储到sb中}
// System.out.println(sb);//在内存中替换占位符String a = sb.toString();a = a.replace("name","韩延丰");a = a.replace("address","济南");//将替换过的内容输出到文件 ,内存到文件wr = new FileWriter("F:\\前端 works\\html\\def.txt");wr.write(a);System.out.println("输出成功");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {if(wr!=null) wr.close();if(re!=null) re.close();} catch (IOException e) {e.printStackTrace();}}
自带缓冲区的字符流
缓冲区大小:默认是一行
BufferedReader / BufferedWriter
package MyPackage;import java.io.*;public class Test9 {//自带缓冲区的字符流public static void main(String[] args) {Reader re = null;Writer wr = null;BufferedReader br = null;BufferedWriter bw = null;//文件到内存try {re = new FileReader("F:\\前端 works\\html\\abc.txt");wr = new FileWriter("F:\\前端 works\\html\\gh.txt");br = new BufferedReader(re);bw = new BufferedWriter(wr);// char[] buf = new char[4];
// int len = -1;StringBuffer sb = new StringBuffer();
// while ((len = re.read(buf))!=-1){
// sb.append(buf,0,len);//将每次读取到的数据存储到sb中
// }
// System.out.println(sb);String line = null;while ((line = br.readLine())!=null){sb.append(line);}//在内存中替换占位符String a = sb.toString();a = a.replace("name","韩延丰");a = a.replace("address","济南");//将替换过的内容输出到文件 ,内存到文件// wr.write(a);bw.write(a);System.out.println("输出成功");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {/*** 先关出,在关入* 从外往内关 br外 = new BufferedReader(re内);*/try {if(br!=null) br.close();if(bw!=null) bw.close();if(wr!=null) wr.close();if(re!=null) re.close();} catch (IOException e) {e.printStackTrace();}}}
}
二进制流
DataInputStream / DataOutputStream
二进制流 对象 = new 二进制流(字节流);
package MyPackage;import java.io.*;public class Test10 {//二进制流public static void main(String[] args) {InputStream in = null;OutputStream out = null;InputStream di = null;OutputStream dataout = null;//abc.txt -> 内存 -> xyz.txttry {in = new FileInputStream("F:\\前端 works\\html\\abc.txt");di = new DataInputStream(in); //字节流 --> 二进制流out = new FileOutputStream("F:\\前端 works\\html\\xyz.txt");dataout = new DataOutputStream(out); //字节流 --> 二进制流//一次开辟10字节内存byte[] buf = new byte[10];int len = -1;while ((len=di.read(buf))!=-1){dataout.write(buf,0,len);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {if(di != null) di.close();if(dataout!=null) dataout.close();if(out!=null) out.close();if(in!=null) in.close();} catch (IOException e) {e.printStackTrace();}}}
}
装饰模式
IO设计的核心思想
在不影响原有对象的前提下,无侵入的给一个对象增加一些额外的功能
网络编程
IP地址:网络上的唯一标识
ip的组成:32位,由4个8位二进制组成
协议:为了让网络中不同的计算机之间能够相互通信而建立的规则,标准,约束。
- TCP协议:面向连接的,可靠的(不丢失,不重复,有序),基于字节流的传输通信协议,传输速度相对较慢
- UDP协议:无连接的协议。提供不可靠的数据传输,传输速度相对较快
socket
socket (套接字):基于TCP协议的网络通信技术,可以提供双向安全连接的网络通信。
scoket需要借助于数据流(字节流)来完成数据的传递工作
模板:1.客户端建立连接,服务端准备服务(ip:端口)
2.通过socket生成OutputStream 以及 InputStream(准备发送数据)
3.使用OutputStream / InputStream 发送接收数据
4.关闭OutputStream / InputStream /socket
//服务端
package SocketProject;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class MyServer {public static void main(String[] args) {ServerSocket serverSocket = null;Socket socket = null;InputStream in = null;BufferedReader reader = null;OutputStream out = null;// 1.准备服务,ip:默认本机127.0.0.1 端口8080try {serverSocket = new ServerSocket(8080);//准备完毕,可以监听客户请求//accept() 用于监听客户端连接System.out.println("服务端启动");socket = serverSocket.accept();System.out.println("服务端检测到客户端连接成功");// 2.通过socket生成OutputStream 以及 InputStream(准备发送数据)// 3.使用OutputStream / InputStream 发送接收数据in = socket.getInputStream();reader = new BufferedReader(new InputStreamReader(in));String info = null;while ((info = reader.readLine()) != null){System.out.println("服务端-------"+info);}//服务端做出反馈out = socket.getOutputStream();out.write("welcome".getBytes());} catch (IOException e) {e.printStackTrace();}finally {try {// 4.关闭OutputStream / InputStream /socketif(reader!=null) reader.close();if(out!=null) out.close();if(in!=null) in.close();if(socket!=null) socket.close();if(serverSocket!=null) serverSocket.close();} catch (IOException e) {e.printStackTrace();}}}
}
//客户端
package SocketProject;import java.io.*;
import java.net.Socket;public class MyClient {public static void main(String[] args) {Socket socket = null;OutputStream out = null;InputStream in = null;BufferedReader bufferedReader = null;try {socket = new Socket("127.0.0.1",8080);System.out.println("客户端连接成功");out = socket.getOutputStream();out.write("hello".getBytes());socket.shutdownOutput();//接收服务端返回的数据in = socket.getInputStream();bufferedReader = new BufferedReader(new InputStreamReader(in));String info = null;while ((info = bufferedReader.readLine())!=null){System.out.println("客户端----------"+info);}} catch (IOException e) {e.printStackTrace();}finally {try {if(bufferedReader!=null) bufferedReader.close();if(in!=null) in.close();if(out!=null) out.close();if(socket!=null) socket.close();} catch (IOException e) {e.printStackTrace();}}}
}
对象流
网络传递一个对象:1.将要传递的对象序列化 2.使用对象流(ObjectInputStream/ObjectOutputStream)
多客户端问题
思路: 客户端代码不变;服务端:每当有一个客户端,就开启一个新线程去处理(每个线程专门处理一个客户端对象)。
UDP的实现
DatagramPacket(数据):封装了数据报的数据,数据长度,目标地址和目标端口
DatagramSocket(收发器):接收发送DatagramPacket中封装好的数据
网络编程中的一些工具类
InetAddress
package demo01;import java.net.InetAddress;
import java.net.UnknownHostException;public class InetAddressDemo {public static void main(String[] args) {InetAddress host = null;try {//获取本机iphost = InetAddress.getLocalHost();System.out.println(host);//获取网络中任意一台InetAddress ip163 = InetAddress.getByName("www.163.com");System.out.println(ip163);} catch (UnknownHostException e) {e.printStackTrace();}}
}
URL / URLConnection(连接)
以下示例,注意点:输入流url->内存 ;输出流 内存->本地
package demo01;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
//从网络上下载源码到本地, 网络->内存->本地
public class URLDemo {public static void main(String[] args) {URL url = null;InputStream in = null;OutputStream out = null;URLConnection urlConnection = null;try {url = new URL("http://www.163.com");urlConnection = url.openConnection();in = urlConnection.getInputStream();out = new FileOutputStream("F:\\前端 works\\html\\xyz.txt");byte[] buf = new byte[64];int len = -1;while ((len = in.read(buf))!=-1){out.write(buf,0,len);}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {out.close();in.close();} catch (IOException e) {e.printStackTrace();}}}
}
反射
反射机制是在运行状态中:
- 对于任意一个类,都能够知道这个类的所有属性和方法
- 对于任意一个对象,都能够调用他的任意一个方法和属性
反射提供的功能
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
- 生成动态代理
package demo02;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class ReflectDemo {//通过反射获取类public static void test01(){//获取反射对象(反射入口):Class//3种方法 1.Class.forName(全类名) 2.类名.class 3.对象.getClass()//1.Class.forName(全类名)try {Class<?> aClass = Class.forName("demo02.Person");System.out.println(aClass);} catch (ClassNotFoundException e) {e.printStackTrace();}//2.类名.classClass<?> bClass = Person.class;System.out.println(bClass);//3.对象.getClass()Person person = new Person();Class<? extends Person> cClass = person.getClass();System.out.println(cClass);}//通过反射获取方法public static void test02(){//Class入口Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}//获取所有的公共(1.本类以及父类接口中的所有方法,2.符合访问修饰符规律)的方法Method[] methods = aClass.getMethods();for(Method method:methods){System.out.println(method);}System.out.println("=========================");//获取当前类的所有的方法,(1.只能时当前类, 2.忽略访问修饰符的限制)Method[] declaredMethods = aClass.getDeclaredMethods();for(Method declaredMethod:declaredMethods){System.out.println(declaredMethod);}}//获取所有的接口public static void test03(){Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}Class<?>[] interfaces = aClass.getInterfaces();for (Class<?> inter:interfaces){System.out.println(inter);}}//获取所有父类public static void test04(){Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}Class<?> superclass = aClass.getSuperclass();System.out.println(superclass);}//获取所有的构造方法public static void test05(){Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}Constructor<?>[] constructors = aClass.getConstructors();for (Constructor<?> constructor:constructors){System.out.println(constructor);}}//获取所有的公共属性public static void test06(){Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}Field[] fields = aClass.getFields();for (Field field:fields){System.out.println(field);}System.out.println("=====================");//获取当前类的所有属性Field[] declaredFields = aClass.getDeclaredFields();for (Field declaredField:declaredFields){System.out.println(declaredField);}}//获取当前反射所代表(接口)的对象(实例)public static void test07(){Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}Object o = null;try {o = aClass.newInstance();Person per = (Person)o;per.interfaceMehod();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}public static void main(String[] args) {
// test01();
// test02();
// test03();
// test04();
// test05();
// test06();test07();}
}
package demo02;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class ReflectDemo2 {//获取对象的实例,并操作对象public static void test01() throws IllegalAccessException, InstantiationException {Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}Person per = (Person)aClass.newInstance();per.setId(1);per.setName("zs");System.out.println(per.getId()+"===="+per.getName());}//操作属性public static void test02() throws IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}Person per = (Person)aClass.newInstance();Field idField = aClass.getDeclaredField("id");//访问的是private修饰的id,但是private是私有的//修改属性的访问权限,使用反射时,如果因为访问修饰符限制造成异常,可以通过setAccessible(true)idField.setAccessible(true);idField.set(per,1);System.out.println(per.getId());}//操作方法public static void test03() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}Person per = (Person)aClass.newInstance();//无参的Method a = aClass.getDeclaredMethod("a", null);a.setAccessible(true);a.invoke(per,null);System.out.println("====================");//有参的Method b = aClass.getDeclaredMethod("b", String.class);b.setAccessible(true);b.invoke(per,"zs");}//操作构造方法public static void test04() throws NoSuchMethodException {Class<?> aClass = null;try {aClass = Class.forName("demo02.Person");} catch (ClassNotFoundException e) {e.printStackTrace();}Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(int.class);System.out.println(declaredConstructor);}public static void test05() throws ClassNotFoundException {Class<?> aClass = Class.forName("demo02.Person");Method[] declaredMethods = aClass.getDeclaredMethods();for(Method declaredMethod:declaredMethods){System.out.println(declaredMethod);}}public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException, InstantiationException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
// test01();
// test02();
// test03();
// test04();test05();}
}
package demo02;//用反射操作动态数组import java.lang.reflect.Array;
import java.util.Scanner;public class ReflectDemo3 {//通过反射操作一维数组public static void test01() throws ClassNotFoundException {//通过键盘输入Scanner input = new Scanner(System.in);System.out.println("请输入数组的类型:");String type = input.next();System.out.println("请输入数组的长度:");int num = input.nextInt();Class<?> aClass = Class.forName(type);//Array.newInstance(class(类型),个数)Object arr = Array.newInstance(aClass,num);//给数组的一个元素赋值Array.set(arr,0,"zs");System.out.println(Array.get(arr,0));}//通过反射操作二维数组public static void test02() throws ClassNotFoundException {//数组类型位intClass c = Integer.TYPE;//数组的长度int dim[] = {3,3};Object arr = Array.newInstance(c, dim);//从二维数组中获取一行Object arr1 = Array.get(arr, 2);Array.set(arr1,1,369);System.out.println(Array.get(arr1,1));}public static void main(String[] args) throws ClassNotFoundException {
// test01();test02();}
}
RPC
远程过程调用
RPC:1.客户端通过Socket请求服务端,并且通过字符串(或者Class)的形式将需要请求的接口发送给服务端
2.服务端将可以提供的接口注册到服务中心(通过Map保存,key:接口的名字, value:接口的实现类)
3.服务端接收到客户端的请求后,通过请求的接口名字,在服务中心的Map中寻找对应的接口实现类
找到之后,解析刚才客户端发来的接口名,方法名,解析完毕后,通过反射技术将该方法执行,执行完毕后,再将该方法的返回值返回给客户端
文件拆分合并
1.将一个文件拆分成若干个子文件
2.将拆分后的子文件合并成源文件
拆分
package FileProject.Split;import java.io.*;
import java.util.Properties;public class SplitFile {public static void main(String[] args) throws IOException {//待拆分的文件,源文件File resFile = new File("F:\\前端 works\\html\\01_01oracle体系结构.ppt");//拆分后的目录File splitDir = new File("F:\\前端 works\\html\\splitDir");spiltFile(resFile,splitDir);}//拆分public static void spiltFile(File resFile,File splitDir) throws IOException {//判断目录是否存在,如果不存在,则创建if (!splitDir.exists()){splitDir.mkdirs();}//思路:拆分1个输入流,n个输出流// 合并n个输入流,1个输出流(注意顺序)//输入流InputStream in = null;in = new FileInputStream(resFile);//输出流OutputStream out = null;//定义缓冲区为1M,当缓冲区填满时,一次性刷出一个文件byte[] buf = new byte[1024*1024];int len = -1;int count = 1;while ((len = in.read(buf)) != -1){//new File(文件目录,文件名)out = new FileOutputStream(new File(splitDir,count +".part"));out.write(buf,0,len);count++;//关闭流,关闭之前会强行清理缓冲区out.close();}//拆分的时候如果将文件名,分割的数量保留,为后续合并做准备//生成一个配置文件,保存上述描述信息//方式一:
// out = new FileOutputStream(new File(splitDir,count+".config"));//查询当前操作系统的换行符
// String lineSeparator = System.getProperty("line.separator");
// out.write(("filename="+resFile.getName() + lineSeparator).getBytes());
// out.write(("partcount="+(count-1)).getBytes());
// out.close();//方式二 :Properties,将内存中的多个属性以key=value的形式写到硬盘中Properties prop = new Properties();prop.setProperty("filename",resFile.getName());prop.setProperty("partcount",(count-1)+"");//写入硬盘(保存:持久化)out = new FileOutputStream(new File(splitDir,count+".config"));prop.store(out,"注释");out.close();in.close();}
}
合并
package FileProject.Merge;import java.io.*;
import java.util.*;public class MergeFile {/*** 方法一:*public static void main(String[] args) throws IOException {//读取多个拆分后的文件List<FileInputStream> inputs = new ArrayList<>();for (int i=1;i<=4;i++){inputs.add( new FileInputStream("F:\\前端 works\\html\\splitDir\\"+i+".part") );}//指定合并后的文件输出流OutputStream output = new FileOutputStream("F:\\前端 works\\html\\MergeDir\\1.ppt");//将多个输入流依次读入内存,最后再一次性输出到1.pptbyte[] buf = new byte[1024*1024];for (FileInputStream input:inputs){int len = input.read(buf);output.write(buf,0,len);}//关闭流output.close();for (FileInputStream input:inputs){input.close();}}*///方法二public static void main(String[] args) throws IOException {//指定拆分后的文件位置File splitDir = new File("F:\\前端 works\\html\\splitDir");//指定合并后的文件位置File mergeDir = new File("F:\\前端 works\\html\\MergeDir");//软件使用次数if(hasRemainingTries()){//拆分文件Merge(splitDir,mergeDir);}else{System.out.println("试用次数已用完");}}//文件合并public static void Merge(File splitDir,File mergeDir) throws IOException {//合并之前,先读取配置文件信息Properties prop = getProperties();int partcount = Integer.parseInt(prop.getProperty("partcount"));//读取多个拆分后的文件List<FileInputStream> inputs = new ArrayList<>();for (int i=1;i<=partcount;i++){inputs.add( new FileInputStream("F:\\前端 works\\html\\splitDir\\"+i+".part") );}//List-->EnumerationEnumeration<FileInputStream> en = Collections.enumeration(inputs);//多个流-->一个流SequenceInputStream sin = new SequenceInputStream(en);//指定合并后的文件输出流OutputStream output = new FileOutputStream("F:\\前端 works\\html\\MergeDir\\9.ppt");//sin输出byte[] buf = new byte[1024];int len = -1;while ((len = sin.read(buf)) != -1){output.write(buf,0,len);}output.close();sin.close();for (FileInputStream input:inputs){input.close();}}//读取配置文件信息public static Properties getProperties() throws IOException {//找到配置文件的位置String configFileName = "F:\\前端 works\\html\\splitDir\\5.config";Properties prop = new Properties();prop.load(new FileInputStream(configFileName));return prop;}//试用次数,判断是否还有试用次数,将当前用的次数保存在硬盘中,然后每一次使用时和5比较public static boolean hasRemainingTries() throws IOException {Properties prop = new Properties();int count = 0;//每使用一次:1.先获取之前的使用的次数,2.将之前的次数+1//查询本次之前用了几次prop.load(new FileInputStream(new File("F:\\前端 works\\html\\splitDir\\6.config")));String times = prop.getProperty("times");if(times == null){count = 1;prop.setProperty("times",count+"");}else {int timecount = Integer.parseInt(times);timecount++;prop.setProperty("times",timecount+"");if(timecount>5) return false;}prop.store(new FileOutputStream(new File("F:\\前端 works\\html\\splitDir\\6.config")),"try times..");return true;}
}
序列化,反序列化
把对象从内存——>硬盘 序列化
把对象从硬盘——>内存 反序列化
实现序列化和反序列化 对象所属的类必须实现 Serializable 接口
ObjectOutputStream 序列化流 ObjectInputStream 反序列化流
Json
{kay:value,key:value}
下载json库
Map,字符串,对象——>Json : JSONObject json = new JSONObject(Map/字符串/对象);
//a. Map -->Jsonpublic static void demo01(){Map<String,String> map = new HashMap<>();map.put("name","zs");map.put("age","13");JSONObject json = new JSONObject(map);System.out.println(json);//可以得到json的格式:{key:value,key:value}}//b. JavaBean(普通对象)-->Jsonpublic static void demo02(){Person per01 = new Person("zs",13);JSONObject json = new JSONObject(per01);System.out.println(json);//{对象的属性名:对象的属性值;对象的属性名:对象的属性值;}}//c. 字符串-->Jsonpublic static void demo03(){String str = "{\"name\":\"zs\",\"age\":13}";JSONObject json = new JSONObject(str);System.out.println(json);}
文件——>Json对象 思路:文件——>String——>Json
//文件——>Json (file ——> String ——> Json)public void demo04() throws IOException {//文件 -> String//方法一:
// InputStream in = super.getClass().getClassLoader().getResourceAsStream("Json/per.json");
// byte[] buf = new byte[10];
// int len = -1;
// StringBuffer sb = new StringBuffer();
// while ((len = in.read(buf)) != -1){
// //byte[] -> String
// String str = new String(buf,0,len);
// sb.append(str);
// }
// System.out.println(sb);//方法二:commons-io.jarString s = FileUtils.readFileToString(new File("F:\\Idea works\\Javajichu\\src\\Json\\per.json"));//String -> Json
// String s = sb.toString();JSONObject json = new JSONObject(s);System.out.println(json);}
生成Json文件
Json对象.write();
public static void demo05() throws IOException {//准备Json数据Map<String,String> map = new HashMap<>();map.put("name","ls");map.put("age","13");JSONObject json = new JSONObject(map);FileWriter fileWriter = new FileWriter("F:\\前端 works\\html\\1.json");json.write(fileWriter);fileWriter.close();}
JsonArray
JSONArray jArray = new JSONArray();
加密解密
使用异或进行加密解密
异或:a.同为0,异为1
b.一个数,两次异或之后,是原数本身
“xxxx” ——> 异或一次是加密 ;异或两次是解密
package utils;
public class SecurityUtil {//通过异或实现加密,解密 , 传入String ,返回String ;xor:异或 ; i,String对i进行异或public static String xor(String input) {//对每一个字符进行加密,先把字符串变成字符数组 : "abc" ---> {'a','b','c'}char[] chs = input.toCharArray();for(int i=0;i<chs.length;i++) {//对每一位进行加密chs[i] = (char)(chs[i]^3000);//大类型转换为小类型要强转}return new String(chs);}//测试public static void main(String[] args) {//一次异或String str = xor("abc");System.out.println(str);//二次异或str = xor(str);System.out.println(str);}
}
MD5/SHA256
字符串->十六进制串
不可逆
//MD5public static String md5Encode(byte[] input) {return DigestUtils.md5Hex(input);}//SHA256public static String sha256(byte[] input) {return DigestUtils.sha256Hex(input);}
Base64
//Base64加密public static String base64Encode(byte[] input){String result = null;try {Class<?> clazz = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");Method method = clazz.getMethod("encode", byte[].class);result = (String)method.invoke(null, input);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}return result;}//Base64解密public static byte[] base64decode(String input) {byte[] result = null;try {Class<?> clazz = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");Method method = clazz.getMethod("decode", String.class);result = (byte[])method.invoke(null, input);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}return result;}
XML解析
Dom解析
Sax解析
事件驱动:程序再执行时,到n哪个阶段时,自动触发哪个阶段对应的方法
图表
1.使用DefaultPieDataset(饼图) / DefaultCategoryDateset(柱形图,折线图,区域图)对象创建数据集
2.创建JFreeChart对象
3.获取图片(3中方式)
//创建图表的数据
DefaultPieDataset dateset = new DefaultPieDataset();
dateset.setValue("value1", 20.0);
dateset.setValue("value2", 30.0);
dateset.setValue("value3", 50.0);//创建jFree对象
JFreeChart jFree = ChartFactory.createPieChart("DATA pige", dateset);
//获取绘图区
PiePlot pieplot = (PiePlot)jfree.getPlot();//展示1
OutputStream out = response.getOutputStream();
response.setContentType("image/png");
ChartUtils.writeChartAsJPEG(out, jFree, 300, 300);
//关闭流
out.close();//展示2
//ChartUtils.saveChartAsJPEG(new File("F:\\前端 works\\html\\pie.jpg"), jFree, 500, 500);//展示3
String fileName = ServletUtilities.saveChartAsJPEG(jFree, 500, 500,request.getSession());
String url = request.getContextPath()+"/servlet/DisplayChart?filename="+fileName;
request.setAttribute("url", url);
request.getRequestDispatcher("show.jsp").forward(request, response);
绘图区:Point区域
h (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
//Base64解密
public static byte[] base64decode(String input) {byte[] result = null;try {Class<?> clazz = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");Method method = clazz.getMethod("decode", String.class);result = (byte[])method.invoke(null, input);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}return result;
}
## XML解析Dom解析Sax解析事件驱动:程序再执行时,到n哪个阶段时,自动触发哪个阶段对应的方法## 图表1.使用DefaultPieDataset(饼图) / DefaultCategoryDateset(柱形图,折线图,区域图)对象创建数据集2.创建JFreeChart对象3.获取图片(3中方式)```java
//创建图表的数据
DefaultPieDataset dateset = new DefaultPieDataset();
dateset.setValue("value1", 20.0);
dateset.setValue("value2", 30.0);
dateset.setValue("value3", 50.0);//创建jFree对象
JFreeChart jFree = ChartFactory.createPieChart("DATA pige", dateset);
//获取绘图区
PiePlot pieplot = (PiePlot)jfree.getPlot();//展示1
OutputStream out = response.getOutputStream();
response.setContentType("image/png");
ChartUtils.writeChartAsJPEG(out, jFree, 300, 300);
//关闭流
out.close();//展示2
//ChartUtils.saveChartAsJPEG(new File("F:\\前端 works\\html\\pie.jpg"), jFree, 500, 500);//展示3
String fileName = ServletUtilities.saveChartAsJPEG(jFree, 500, 500,request.getSession());
String url = request.getContextPath()+"/servlet/DisplayChart?filename="+fileName;
request.setAttribute("url", url);
request.getRequestDispatcher("show.jsp").forward(request, response);