java基础笔记
"中国".equals("中国")判断字符串是否相等,比较的是内容
工具:editplus,notepad++,sublime text,IDEA,eclipse
javac holle.java 编译文件
java holle 运行文件
class Test01{
public static void main(String [] args){
System.out.println("kabdfa");
}
}
只要类名被 public修饰那么源文件的名字必须和类名保持一致
单行// 多行/**/
反编译:通过反编译软件
基本数据类型:
println打印完会换行,print不会换行
int a=10;
System.out.println(""+a)
二进制转8进制,三位一分,各个求和,最后拼接
二进制转16进制,四位一分
都会以10进制的方式输出。
输出8进制0开头,输出2进制0b开头,输出16进制0x开头。
8 bit=1byte 字节
1024byte = 1kb
1024 kb = 1MB
我.们威的值在byte或煮 shoxt的范围内则无.会有变化
但是当赋的值丕在 byte 或煮short的范围内.则会将此值作为int类.型.处理
错误:过太的整数:2222222222
声明long类型数值的时候要在数值的表属+l/L
建议使用大写的L
浮点型:
1.溪点类型默认的数据类型是 double
2.不兼察的类型:从double转换到float可能会有损失
直明float类型的数据要在数值.的末属+ f/F
建议太家使用F
3.爱点类型底层采用的晟科堂计数法表示
double dl = 3.14e2;
dl = 3.14E2;
char 只能存储一个字符
boolean:只能存储true或false
1.自动类型提升:小的数据类型可以转换为大的数据类型
小的数据类型标识符=(小的数据类型)大的数据类型的值;
int result = a++ + b++ + ++b + ++a;
无论是前++还是后++独立成行成都众绘本身+1
+: 正号
:加号
:字符患连接符
注意:可以使用小括号提高运算的等级
Scanner:接收键盘输入的值
import java.util.*
Scanner input = new Scanner(System.in);必要,可以反复使用
int age = input.nextInt();//接收键盘输入
double height = input.nextDouble();
String name = input.next();
char c1 = name.charAt(0);拿取name中的第一个字符
注意:
1.next()..无法接爱空格之后的内容
2.input.nextLine()可以接爱整行内容包含空格
3.input.nextLine()接收到回车就会终止
在前面创建一行输入接收车防止对下面的内容造成影响
input.nextLine ();
三目运算符可以代替简单的if表达式
if(){
}if else(){
}else(){
}
在switch语句中,支持byte,short,int,char,string
default://可有可无
System.out.println("输入有误");
break;
while(){
}
do{
}while()
随机数公式
math.random()
n:较大的数
m:较小的数
[n,m]
(int)(Math.random()*(n-m+1)+m);
return 会结束类方法
单个个体的变化放在循环里面,求总放在外面
一旦存在label标签 那么结束的是 label所在的循环
l: for(int i =1;i<=10;i++){
for(int j=1;j<=15;j++){
break l;
}
}
continue也一样可以用
如果有一个数的约数 在其开平方的右边 那么必然会有一个约数在其开平方的左边
开平方:Math.sqrt(64);
求从次方:math.pow(2,3); 2的3次方
求质数:
public static void main(String [] args){
l: for (int i=2;i<=200;i++){
for(int j = 2;j<Math.sqrt(i);j++{
if(i%j==0){
continue l;
}
}
System.out.println(i);
}
}
数组定义:
注意:1.数组内元素的类型要保持一致
2.new int [不能放数字]{};
3. 数组的访问,通过数组下标访问元素
静态初始化:
arr.length()
int [] a = {};
int [] arr = new int [] {};
int [] arr2;
arr2 = new int [] {1,2,3};
int arr = new int[1,2];
数组的默认初始化:int 0 ;byte 0 ;double 0 ; float 0.0 ; char '\u0000' 空;boolean false;
动态初始化:
重点循环遍历数组:除了for循环
for (String e: strArr){
System.out.println(e);
}
数组对象的hash的16进制表现
冒泡排序节约时间和资源
二维数组:
int [][] arr;//推荐使用
int [] arr [];
静态初始化:
数据类型[]标识符={{一维数组的的元素},{—维数组的元素}};
数据类型[][]标识符=new 数据类型[][]{{一维数组的元素),{.一维数组的元素]};
double [] [] doubleArr = new double[] [] {{};{}}
int [][] arr = new int [2][];没有定义行的值;
int [0] = new int[]{1,2};给第一行数组进行赋值
int [1] = new int[5];给第一个一维数组长度为5;
动态数组初始化:
数据类型[][]标识符= new数据类型[容量1][容量2];
for(int [] e:arr){
for(int ele:arr){
}
}
idea快捷键:
psvm打main方法();
sout快速输出语句
shift+enter:快速到下一行
ctrl +d :快速删除
ctrL +alt +下:快速复制
alt+上/下 快速移动代码
ctrl+r 替换 ctrl+f查找
alt+enter 快速创建方法
ctrl+shift u 大小写切换
创建对象:实例方法
类名 标识符 = new 类名()
标识符.方法
包名:采用公司网址倒叙
文件->新建->package
com.atguigu.项目名
java.lang 不需要导包
java.io java.net java.util
只要使用的不是本包下的资源 就需要导包
解决:
问题:使用类变量或者叫静态变量解决。
在成员变量前+static ;
public static string country;
实例变量与类变量的区别:
调用方式:
1实例变量:对象名。属性名
类变量:类名。属性名
内存中的分数不一样:
实例变量:每一个对象都有一份
类变量: 当前类 都有对象共享一份
内存中的位置不同:
实例变量:堆中
类变量:方法区
修饰不同:
实例变量:不加static
类变量:加static
package com.atwugu
public class Student {
//实例变量
pubilc String name;
public int age;
//类变量
public static String country;
}
先有类在有对象
静态方法 使用类名.方法名进行调用
如果在本类中 可以省略
定义方法:(和函数区别不大)
[权限修饰符][static] void 方法名(形参列表){}
void 没有返回值
对应返回的类型int,string 等
reture sum;返回值
形参和实参:
方法:封装功能实现代码的复用
静态方法:被static修饰的方法
非静态方法:不被static修饰的方法
不同点:
1.调用方式不同
静态方法通过:类名.方法名调用
非静态方法:对象名.方法名调用
2.静态方法不能【直接】引用非静态的方法或者变量
可以通过创建对象的方式间接引用
3.非静态方法来者不拒静态或者非静态的变量方法都可以直接使用
static:静态的内容已经随着类的加载而加载了,而此时对象肯还没有创建
所以不能使用 对象创建后才分配内存的内容
当有共性的存储时候使用static,避免开辟多余的空间
static int country;相同的国家;例子
public static void change( Point point ){
}
class Point {
public int x;
public int y;
}
数组内存图
public class ChangeValueTest {
public static void main(String[] args) {
String[] arr = {"范冰冰","蔡旭坤"};
System.out.println("changValue ()调用前:arr[e]:" + arr[0]);,changVlue(arr);
System.out.println("changValue ()调用后:arr[0]:" + arr[0]);
}
public static void changValue(String[]arr) i
arr[0] =“韩红";
arr = new String[]{"谢广坤",“赵四"};
System.out.println("changValue ()调用中:arr[0]:" + arr[0]);
}
}
栈与堆 只要是new就是杂堆中开辟空间
对象和数组都是存在堆中
使用final修饰的变量的值不能在改变
可变形参:可以存在多个可变参数
static void sum(int...a){相当于数组 int [] a
}
方法重载:不同的方法可以使用相同的方法名
同一类中同一方法名 不同的形参列表:数量 顺序 类型
方法调用时会根据不同的数据类型自动找到最佳匹配的方法
public static void sum(int m,int n){}
public static void sum(double m,int n){}
public static void sum(int m,double n){}
在dos命令下用java 类名 参数 进行对main函数传参
run --> eidt configurations --> main class是自己运行的那个类 -->program argument.
静态导入:导入一个类中的所以静态资源
递归:指在挡前方法内调用自己的这种现象
直接递归,间接递归
递归两个条件:
public static void main(String[] args){
int sum = getSum(5);
System.out.println(" "+sum);
}
public static int getSum(int sum){
if(num == 1){
return 1;
}
return num + getSum(sum - 1);
}
斐波拉契数列:
对象类型的数组:数据类型 [] 标识符 = {数据类型的元素}
封装:
获取内容,传递赋值
public class Person {
private String name;
private String sex;
private int age;
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
构造器:可以快速给成员变量赋值
[权限修饰符] 类名 (形参列表){}
1.每一个类中都会有一个默认的无参的构造器 但是当声明有参的构造器之后默认的无参的构造器就会消失
2.建议自定义类都【手动】提供一个默认的无参的构造器
3.构造方法实际上是一个特殊的方法
当局部变量与成员变量相同是要加this
5.构造器/构造方法/构造函数是可以重载的
public class Student{
string name;
int age;
int score;
double height;
public Student(String name, int age, int score, double height){
this.name = name;
this.age = age;
this.score = score;
this.height = height;
}
}
对属性的封装:
使用继承 用关键字 extends
语法 [权限修饰符] 子类 extends 父类
继承后可以使用父类的资源
this 代表当前对象
super 代表从父类继承过来的资源
当子类没有此资源而父亲有时则使用super和 this没有区别
this:代指当前对象使用的是从父类继承的资源
super:直接使用的是父亲的资源
当父类的方法不能满足子类的需求时要进行方法的重写。
子类在使用资源时(属性(成员变量)方法)优先在本类中查找
当本类中没有时才去父类中查找一点一点向上找直到找到object类
Object类是所有类的父类
如果一个类没有显示的继承另一个类那么此类默认继承自object类
方法重写:
方法重写的注意点:
1.当子类重写父类的方法时访问权限不能比父类方法的访问权限更加严格 >=父类方法的访问权限
2.返回值类型
2.1当父类的返回值类型是基本类型数据时则子类必须与父类保持一致
2.2当父类的返回值类型是引用类型数据时则子类可以是返回父类也可以返回子类
3.方法重写时子类的形参必须与父类的形参保持一致否则就相当于在子类中新增一个方法
4.关于异常
继承方法练习
2、声明子类:Student类,继承Person类新增属性:score成绩
属性私有化,get/set
包含getInfo()方法:例如:姓名:张三,年龄:23,性别:男,成绩:89
this: 1.可以用来区分成员变量与局部变量
2.可以用来调用本类中的构造器根据数据类型进行匹配不是根据变量名
调用本类构造器必须位于首行
一般多参调少参
1.每一个构造器的首行 都会有一个默认的隐藏的super() 调用父类的无参构造器
2.当出现this ()调用本类中构造器时那个默认的super()自动消失
3.可以使用super(参数)调用父类有参的构造器
4.可以使用super.去调用父亲的方法
可以使用super.父类的属性
代码块就是 {} 括起来
静态代码块 static {}
静态代码块:用于给静态变量进行赋值
静态代码块只会创建一次再次创建n个对象也不会再执行
先于构造器执行
执行顺序按照从上到下执行
类的成员:成员变量成员方法构造器代码块
成员代码块:用于给成员你变量赋值
每创建一个对象就会执行一次早于构造器执行
安照代码块的书写顺序执行
给成员变量赋值方式:
1.默认值
2.直接赋值
3.代码块赋值
4.get/ set赋值
5.构造器赋值
静态变量 不建议采用构造器赋值 他是属于类的 可以使用类名.属性 进行赋值
类的初始化是对类的静态成员变量赋值
实例初始化:给非静态成员变量赋值
先执行对变量显示初始化的代码
才会去执行构造器的内容
1.当调用子类的无参构造器时 因为子类无参构造器的首行有super()调用父类无参构造器
先给父类成员变量进行初始化进入父类无参构造器-->回到子类无参构造器-->
执行子类成员变量的初始化--->执行子类无参构造器--->回到创建对象的位置
类初始化先执行<clinit>
实例初始化
进行实例初始化时如果子类重写了父类的方法那么执行的是子类重写的方法
如果有父类会执行两次<init>子类一交父类一次
封装:隐藏内部的实现细节只对外暴露少量的接口供外界访问
属性的封装
方 法对功能的封装
类 对方法的封装 Math
包 对模块的封装 java.util. Scanner
继承:实现资源的复用
方法
属性
实现多态的条件:
1.有继承
2.有方法重写
3.父类的引用指向子类的对象
多态有两种状态:左边是编译时状态=右边是运行时状态
编译时状态运行时状态
多态创建的对象能够调用什么方法要看编译时状态
运行是状态:当代码跑起来(右键run)对象是谁
编译时状态 运行时状态
Animal ani = new Cat();//父类的引用指向子类的实例
public c1ass Test {
public static void main(String[] args){
/*Chinese ch = new Chinese();
showEat(ch);*/
Indian indian = new Indian();
showEat(indian);
/*English english = new English();
showEat(english);
Japan japan = new Japan();
showEat(japan);*/
}
public static void showEat(Programmer programmer){//Programmer programmer = indian;
programmer.eat();}
}
public class Programmer{
public void eat(){ System.out.println("吃饭"); }
}
class Chinese extends Programmer{
public void eat(){System.out.println("吃饭");}
}
多态的作用存储不同的数据类型
用数组进行存储
Animal[] aniArr = new Animal[2];Animal类型的数组
Dog dog = new Dog();
dog.name =“旺财";
Cat cat = new Cat();
aniArr[0] = dog;
aniArr[1] = cat;
多态方法应用于方法的返回值类型
public 父类型 方法名(){
return 子类对象();
}
向上转型:不能使用子类独有的资源
向下转型:使用子类自己所独有的资源的时候down casting
前提:已经完成了向上装型;
小的数据类 型标识符=(小的数据类型)大的数据类型的数值。
Animal ani = new Dog();
Dog dog = (Dog)ani;
在转型前可以用instanceof进行判断类型是否相同
instanceof:判断左边的对象是否是属于右边类型
2.想要使用子类自己所独有的资源(方法属性)必须向下转型
放的什么数据要创建什么类型的对象
SalaryEmployee s1 = new SalaryEmployee(name: 赵四" , new MyDate( year: 2010, month: 2,,day: 1),salary : 1000,workDays:20,
虚方法:可以重写的方法
非虚方法:不可以重写的方法 静态方法 独有方法 使用final修饰的方法 构造器
native关键字:
final关键字:
修饰类时此类不能被继承(太监>public final class Animal {}
final修饰的方法子类不能重写public final void eat(){}
finaL修饰的【变量:不仅有成员变量也有局部变量】是常量固定不变的量﹑不能修改
final修饰的对象地址值不能改变//本质是值不能改变
Object类:
toString()
不想看相关地址信息 想看属性信息重写toString();
public String toString(){
return "名字是" +name +”年龄是"+age +”身高是" +height;
}
getClass():获取运行时的类型
多态创建的哪一个实际对象
finalize():
对象被回收之前会调用finalize()方法
hashCode():重写hashCode
如果两个对象的hash值是不同的,那么这两个对象一定不相等;
如果两个对象的hash值是相同的,那么这两个对象不一定相等。
equals():只能比较引用类型数据
如果没有重写 比较的是地址值
==:比较基本类型数据比较的是值
比较引用数据类型比较的是地址值
因为浮点类型存储的是约数不建议使用==比较浮点类型
浮点数1==浮点数2返回日
浮点数1>浮点数2返回正数
浮点数1<浮点数2返回负数
Double.compare(浮点数1,浮点数2)
空指针异常:
以后遇到最多最简单的异常:
1.对象空
2.参数空
注意:
使用自己确定的值调用方法防止出现 NuLLPointerException;
抽象类:
public abstract class Animal{
}
1.如何定义抽象类?
[权限修饰符] abstract class类名
2.如何定义抽象方法?
[权限修饰符] abstract返回值类型方法名(形参);
3.抽象类不能创建对象所有的功能都需要子类去实现
抽象类一组功能的集合如果是我的孩子则必须有这些功能
4.如果一个类继承了一个抽象类那么此类必须实现父类中所有的抽象方法
5.抽象用于表示is a的关系
Cat is a Animal
Doq is a Animal
6.抽象类中可以没有抽象方法可以存在普通的资源普通变量普通的方法
7.抽象方法必须存在于抽象类中
接口:
public interface Fly(){
}
1.如何声明接口:
[权限修饰符]interface接口名{}
2.如何使用接口
让一类实现接口
cLass A implements接口名{
3.如果一个类实现了一个接口那么此类可以看做此类的孩子
Fly fly = new bird();
fly.fly;
接口中的抽象方法默认被public abstract修饰
接口中的变量默认被public static final修饰
1.一个类可以实现多个接口
2.一个类实现接口后如果不想实现接口中的抽象方法则自己必须变为抽象类
3.接口的成员
全局静态常量被public staic fianl修饰抽象方法
默认方法
静态方法
以上内容通通默认被public修饰
4.接口可以多继承
public interface sLeep extends Fly,Eat{}
如果一个类实现了继承了多个接口的接口那么不仅要实现此接口的抽象方法也要实现继承接口的抽象方法
5.一个类可以先继承一个父类再去实现多个接口顺序不能改变
class Dog extends Animal implements Sleep{}
当出现同名的方法则必须进行重写否则报错
还可以在重写的方法内
接口名.super.方法名();
Study. super.study();
comparable():引用类型的比较规则,重写方法
一.引用数据类型比较
Comparable:[内部]比较器
Comparator:[外部]比较器
二.使用内部比较器比较Comparable
1.让想要比较的对象的【类】实现 Comparable接口
2.实现接口后重写comparaTo()方法
3.在重写的方法内定义比较规则
前一个数大于后一个数返回一个正数
前一个数小于后一个数返回一个负数
前一个数等于后一个数返回一个零
public int compareTo(Object o){//Object o = p2;
Person p=(Person)o;//向下转型
return this.age -o.age;
}
通用排序放方法
public static void sort(Object[] objArr){//0bject arr = student;
for (int i=0;i<objArr. length - 1; i++){
for (int i=0;i<objArr. length -1-i;j++t){
Comparable s = (Comparable)objArr[il;
Comparable s1 = (Comparable)objArr[i +1];1/当前一个数大于后一个数
if (s.compareTo(s1)>0){
object temp = objArr[i];
objArr[j] = objArr[i +1];
objArr[i +1]= temp;
}
}
}
}
public static void sort(Comparable[] objArr){//Comparable arr = student;
for (int i=6; i< objArr. length - 1; i++){
for (int i =0; i<objArr. length - 1 - i;j++){
//当前一个数大于后一个数
if(objArr[i].compareTo(objArr[i +1])>0){
Comparable temp =objArr[i];
objArr[ji] = objArr[i+ 1];
objArr[i +1]= temp;
}
}
}
}
如何使用外部比较器比较:
外部比较器:因为在比较对象类的外面新建了一个类专门用于比较
1.定义一个类实现Comparator接口
public class PersonSort0fAge implements Comparator {}
2.重写compare()传递两个参数
3.制定比较规则
4.先去创建比较规则的对象
通过对象调用compare()再传入对象
枚举:
在1.5之前构造器私有 属性变为常量
1.构造器默认私有
2.枚举中的属性必须位于枚举元素的下面
3.所有的自定义枚举默认继承自Enum类
4.枚举类不能再继承其他的类
5.枚举类可以实现一个接口
6.枚举对象可以根据自身的需求灵活判断是否需要自定义接口内的方法
获取枚举对象的方法1.枚举类.枚举对象
Season spring = Season. SPRING;
2.通过valueof方法
SeasonSeason. valueof("枚举对象的名字");//返回所有的枚举对象
Season[ seasons = Season. values();
包装类:
常见的包装类型有:
byte short int Long float double char booLean
Byte Short Integer Long FLoat Double Character Boolean
基本类型数据与包装类之间的转换:
1.基本类型数据--->包装类型
方式一:通过构造器
Integer标识符=new Integer(基本类型数据);
方式二:
Inteher标识符= Integer.valueof(基本类型数据)
老方法:
新方法 直接采用自动装箱 直接将 基本类型数据 赋值为引用类型的对象
Integer in =基本类型数据。
自动装箱的底层采用的是工nteger.valueof(a);
2.包装类型--->基本类型数据
方法一:调用包装类对象的intValue();
方法二:自动拆箱
直接将引用类型数据变为基本类型数据
基本数据类型 标识符 = 包装对象
1.字符串--->基本数据类型/包装类型
方法一:
Integer.parseInt("字符串纯数字");
如果不是纯数字会报异常 NumberFormatException
方法二:
Integer in = new Integer("字符串纯数字");
如果不是纯数字会报异常 NumberFormatException
其他包装类型以此类推:
DoubLe.parseDouble(“字符串小数);
double v= Double.parseDouble(age);
基本类型数据转换为字符串:
1.""+基本类型的数值
2.String. valueOf();
包装类型对象的缓存问题:
包装类型有一个缓存区:Byte
Short
Integer
Long [-128,127]
Character [0,127]
BooLean true false;
单元测试:jUnit 百度下载工具
内部类:杂类的内部在定义一个类
外部类:内部类外边的类叫外部类
外部类只能被public与default修饰
静态内部类:
一、语法结构:
class 外部类名{
//内部类定义
[权限修饰符4种]static [final] class类名{
}
二.作用
1.可以打破java单继承的限制
2.在内部类中做更多的功能为外部类服务
3.可以资源的隐藏
三.特点:
1.静态内部类可以访问外部类的资源
静态的属性
静态的方法
2.外部类能否使用内部类的资源
如果是静态资源可以直接通过内部类名.资源名
如果是非静态资源那么需要通过内部类的对象.资源名
3.当类中有内部类的时候
外部类名$内部类名
//创建内部类对象
Outer. Inner inner = new Outer. Inner();
inner.innerMethod();
非静态内部类:
不加static修饰的 内部类
外部类 类名{
[权限修饰符] class 内部类名 {
}
}
特点:
1.非静态内部类可以直接使用外部类所有的资源
静态与非静态资源
私有与非私有资源
2.外部类使用内部类的资源
1.首先创建非静态内部类的对象然后才能使用内部类中的资源
2.如果是内部类中的静态常量则可以直接使用
3.外部类的静态放啊发不能使用内部类资源
3.非静态内部类中不能存在静态的方法静态的属性
但是可以存在静态的常量
4.有几个非静态内部类 酒水生成几个字码节文件
外部类名$内部类名
//outer outer = new Outer();
//Outer.Inner inner = outer.new Inner();
//System.out.println(outer.num);
/使用非静态内部类对象
outer.Inner inner = new Outer().new Inner();//等同于上面的写法
局部内部类:局部变量【特别不重要】
语法结构:
外部类类名{
[权限修饰符][static]返回值类型方法名(形参列表){
[修饰符]class类名{
}
}
}
注意:
1.局部内部类只能被default修饰
2.局部内部类可以被final /abstract修饰
3.局部内部类使用外部类的资源要看外部类的方法是静态还是非静态
方法为非静态可以使用外部类静态或者非静态的资源
方法为静态可以直接使用外部类中静态的资源
4.局部内部类编译成功后也会产生对应的字节码文件
外部类的名字$序号内部类的名字
Person$2Inner.class
5.局部内部类中不能存在静态的属性但是可以存在静态的常量
6.在方法内创建内部类对象通过内部类对象调用内部类中的方法
7.当在局部内部类的方法内使用局部变量时那么变量前会自动加一个final
匿名内部类:
匿名内部类:没有名字的类
匿名对象:没有名字的对象
方式一:
new父类(){
重写父类的方法
}
创建了一个子类但是子类是没有名字的
方式二:
new父类(实参列表){
重写父类的方法
}
创建了一个子类但是子类是没有名字的
方式三:
new父接口(){
重写接口中的方法
}
创建了一个子类但是子类是没有名字的
1.匿名内部类也会生成独立的字节码文件外部类的名含序号.cLass
2 匿名内部类不可以存在静态的变量但是可以存在静态的常量
使用内部类:
1.在完成内部类的声明的时候已经创建了内部类的对象
2.匿名内部类创建的是子类对象可以使用子类重写父类的方法已经从父类继承过来的资源
3.可以使用接口或者抽象类作为形参传递一个孩子
method1(new FLy(){
@Override
public void fLy(){
system.out.printLn("超人会飞);
}
});
}
pubLic static void method1(FLy fly){
fly.fly();
}
注解:
常用注解:
@override 判断当前方法是不是重写的方法
@Deprecated
标记类或者方法过时
过时指的是不推荐使用使用不会报错
Suppresswarnings
抑制警告
使用javadoc生成API文档
在idea工具中进行生成
Throwable是所有异常的祖师爷
Error:
处理不了此异常
StackOverfLowError:栈溢出溢出
outOfMemoryError
Exception:重点******
程序员能处理的异常
Exception:分为两种
运行时异常:
代码写完不报错 运行起来才报错 RuntimeException
编译时(检查)异常:checkedException
写完代码就报错检查异常
发生异常时如果没有进行处理
会一层一层的向上抛出最终交给JVM处理终止程序输出对应的信息
异常处理:
两种方案
1.tryicahtch(){}
2.throw throws 抛出异常
二.使用 try{}catch(){} 处理
try{
可能发生异常的代码
}catch(异常类型标识符){// 此位置已经创建了一个异常对象
对异常进行处理
}
注意:
1.变量的作用域
try中声明的变量仅仅在try中有效
2.当发生异常后 try语句块内异常下面的额代码不再执行==》进到 catch内 =z=>处理异常==z》进行try{}catch(){}下面的内容
3.如果没有发生异常则不会执行catch()中的内容
4.如果发生了没有捕获(声明)的异常则程序立即终止不会继续向下执行
5.当try语句块代码可能发生多个异常时我们可以声明多个异常
5.1方式一
catch(异常类型/异常类型标识符){
}
catch (ArrayIndexOutOfBoundsException / InputMismatchException e)
5.2方式2
采用多重catch()
try{}catch(异常类型1标识符){
}catch(异常类型2标识符){
}。。。。 。 。
发生了什么异常就会进到 对应的catch中
6.如果采用了多重catch那么可以省略为一个Exception
必须放到多重catch的末尾否则报错
子类异常在前面父类异常在后面
finally:最终的
无论发生还是没有发生异常不管异常有还是没有捕获都会执行
方式一:
try{}catch(异常类型e){
}finally{
最终会执行的代码
}
注意:
1.在程序没有发生异常时有return语句要先执行finally再执行返回操作
2.在catch语句块内进行return那么也要先执行finally再执行返回操作
3.如果在finally中存在 return那么无论前面在那个位置有return都会返回
finally中的return的值
处理异常的方式二:
通过throw 抛出异常 (自定义异常的输出信息)
注意:
1.如果是运行时异常则直接throw即可
2.如果是编译时异常那么必需在throw后 在方法的声明处通过throws表名由调用此方法的方法 处理异常
3.throws在方法的声明处告诉调用我方法的方法随便掉但是需要处理我声明的异常
4.throw一次只能抛出一个异常对象
throw下面不能存在其他的内容
方法重写:
1.权限修饰符不能比父类更加严格>=父类的访问权限
2.返回值类型
基本类型数据 必须与父亲保持一致
引用类型数据 可以是父类 也可以是父类的孩子
形参列表必须保持一致
子类不能抛出比父类更大的异常
注意:编译时异常有效
数组复制:
System. arraycopy(src,srcPos , desc,descPos , length);
src:数据源
srcPos:数据源开始的下标
dest:目标数组(目的地)
descPos:目标数组开始的下标
length:复制的长度长度数量
//数据源
int[]arr = {10,20,30};
//目的地
int[]newArr = new int[3];
System. arraycopy (arr ,1 , newArr ,0,2);
System.out.print1n(Arrays.tostring(newArr));
多线程:
Thread.currentThread().getName():获取当前线程的名字
创建两条线程:
采用继承的方式创建多线程
1.创建一个类继承Thread类
2.重写run()方法创建多线程做的事情
3.启动线程
创建线程对象
RabbitThread rabbitThread = new RabbitThread();
使用线程对象调用start();完成启动
.setName()修改名字
使用实现的方式创建多线程
1.创建一个类型实现 RunnabLe接口
2.重写run()方法
3.创建 Runnable对象
4.创建Thread对象将 Runnable对象作为参数进行传递
5.调用start()方法启动线程。
public static void main(String[] args){
//1.创建Runnable对象
RabbitRunnable rabbitRunnable = new RabbitRunnable();
//2.创建Thread类将 Runnable对象作为参数进行传递
Thread t1 = new Thread(rabbitRunnable);
Thread t2 = new Thread(rabbitRunnable);
t1.start();//开启线程
继承的方式与实现的方式做对比:
1.继承的方式简单
2.实现的方式可以更好的实现资源共享
线程常用的方法:
isAlive():判断当前线程是否处于活动状态
setPriority(优先级):
1<=优先级<= 10
如果没有指定优先级则默认的优先级都是5
优先级特别低也会有执行的机会
先去执行优先级高的再去执行优先级低的
4.Thread.sleep(数字):让当前线程 睡眠一段时间 单位是ms
5.join() 强行插队 插队的乡村 调用 join() 那么 被插队的线程要进行等待
等 插队的线程执行完毕后 才能继续执行
守护线程:
t1.setDaemon (true);
哪一个线程调用了setDaemon (true)则此线程就是一个守护线程
volatile:保证线程的可见性
static volatile boolean flag = true;
解决线程安全问题方式一使用同步代码块
synchronized(同步监视器对象){
}
同步监视器对象:
1.必须是引用数据类型
2.当多条线程操作共享数据同步监视器对象必维是同一个
3.同步代码块的意义
使用同步方法:
同步方法 同步监视器对象是this
当有一条线程 进入同步方法那么 其他线程 不仅不能进入此方法
也不能进入拥有通一同步监视器对象的同步方法
public class SynchronizedMethod {
public static: void main(String[] args){
WindowRunnable1 windowRunnable1 = new windowRunnable1();
Thread t1 = new Thread(windowRunnable1,name:"窗口一");
Thread t2 =new Thread(windowRunnable1,name:"窗口二");
Thread t3 =new Thread(windowRunnable1,name:"窗口三");
t1.start();
t2.start();
t3.start();
} }
class WindowRunnable1 implements Runnable {
int count = 60;
@Override
public void run({
whie (true){
if (count<=0){
break;
}
this.saleTicket();
}
}
private synchronized void saleTicket({//this
if (count <= 0){
return;
}
try{
Thread.sleep( millis: 10);
}catch (InterruptedException e){
e.printStackTrace();
System.out. println(Thread.currentThread().getName() +"卖了第"+ count +"张票");
count--;
}
线程通信:
1.wait():进行等待
2.wait(时间):
3.notify:通知 如果有多个线程等待则随机通知一个线程
notifyAll():通知所有等待的线程起来干活
死锁:让一条进程先跑完就行了
基础API与常见的算法:
Math:构造器私有 方法都是静态方法
BigInteger: 存储大的整数
BigDecimal: 用于存储确切的小数
add() divide() multiply() subtract() remainder()
加 除 乘 减 求余
// 20代表保留多少位小数
System.out.println("b1.divide(b2) = " + b1.divide(b2,scale: 20,BigDecimal.ROUND_CEILING));
Random random = new Random();
random.nextInt(n)
[e,n)范围内的int类型的随机数
当种子固定的时候产生的随机数是相同的
Date类:
将当前时间 转为long值;
long time = date.getTime();
//将 date对象输出为一个字符串
String time = date.toLocalString();
sql.date只有年月日没有时分秒
注意:当出现了同名类型需要全路径导入
类名+包名
*属性:year month*
值:整数向前+
负数向后-
calendar.add(属性,值);
获取时区:
String[] availableIDs = TimeZone.getAvaliableIDs();
日期转换
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH : mm: ss E");
日期--->字符串
df .format(目期对象);
date --->2020 2020-11-1114:48:33 星期三 2020年11月11日 14:48:33 格式可以变化
字符串--->日期
Date date =df .parse(字符串);
注意:
要解析的字符串内容必须与格式完全匹配否则报错
java.text.ParseException: Unparseable date: "2020-11/1114:53:28"
LocalDate:年月日
不可变的日期 一旦对日期做出修改会生成一个新的LocalDate记录改变后的日期
minusDate(2)减少日期
LocalDate now = new LocalDate()
System.out.print1n(now);
int year =new.getYear();
System.out.print1n(year);
Month month = now.getMonth();//NOVEMBER
System.out.println(month.getValue());
LocalDate of = LocalDate.of( year: 2020,month: 1,dayOfMonth: 1);
System.out.println(of);
Loca1Date localDate = of.plusDays(2);
System.out.print1n( localDate);
LocalTime时分秒
Loca1DateTime年月日时分秒
时间间隔:
持续日期/或者时间:Period和Duration
Loca1Date l1 = Loca1Date now();
Loca1Date l2 = Loca1Date.of(2000,11,10);
Period period = Period.between(l1,l2);
间隔多少时间:
Druation duration = Druation.between(l2,l1);
DateTimeFormatter有提供好的模板直接使用
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String str = "2020-11-1115:47:53";
LocalDateTime time = LocalDateTime.parse(str, formatter1);
System类:
gc();
idea自定义模板:百度
数组扩容:
//把新数组的地址赋给旧数组
String strArr = {"1","2","3"};
String[] arr = new String[strArr.length*2]
strArr = newArr;
数组的插入:
arraycopy();
直接选择排序:
数组工具类:
sort()排序
安装指定的范围添加元素
Arrays.fill(arr,开始下标,结束下标,填充的元素);[开始下标,结束下标);
//复制旧数组 创建新数组
String[] s2 = Arrays.copyof(s,2);
Arrays.copyOf Range(数组名,开始下标,结束下标);
[开始下标,结束下标)
Array.equals(a1,a2);
比较的是内容 以及下标 是否完全一致 返回true false
使用二分查找数组必须有序
当返回小于0的数则说明数组内不含有此元素
int i = Arrays.binarySearch(arr, key: 3);
字符串的拼接:
String hello =new String( original: "he11o");
System.out.println(hello -= s1);//false
//hello.intern()调用此方法会将数据直接存到常量池
System.out.println(hello.intern() ==s1);//true
空与非空:
String a = null;
String a1 = "";//空的字符串 有内容
字符串的常用方法:
(1) boolean isEmpty():字符串是否为空
(2) int length():返回字符串的长度
(3) String concat(xx):拼接,等价于+
(4) boolean equals(Object obj):比较字符串是否相等,区分大小写
(5) boolean equalslgnoreCase(0bject obj):比较字符串是否相等,区分大小写
(6) int compareTo(String other):比较字符串大小,区分大小写,按照Unicode编码值比较大小
(7) int compareTolgnoreCase(String other):比较字符串大小,不区分大小写
(8) String toLowerCase():将字符串中大写字母转为小写
(9) String toUpperCase():将字符串中小写字母转为大写
(10) String trim():去掉字符串前后空白符,两端的空格。
contains("a")判断是否包含指定的字符串
indexOf("a")查看指定元素第一次出现的下标;
lastindexOf()最后一个出现的元素,不存在返回-1;
subString()截取指定范围内的字符串
getBytes();字符编码
startWith()查看是否是以该元素开头
endsWith()以什么开头
replace("12","34")用12代替34,不支持正则
replaceAll("正则","value")替换所有匹配的部分
replaceFrist("正则","value")替换第一个匹配部分
split(".")按照点分割
String是不可变的字符,序列涉及到字符串的改变,会创建大量的对象
--StringBuffer 一个是线程安全的 效率低
底层是采用char类型的数组存储数据 char数组 默认长度是16
--StringBuilder 线程不安全的 效率高
可变的字符序列
底层是采用char类型的数组存储数据 char数组 默认长度是16
共同点:
他们的父亲都是 AbstractStringBuilder抽象类
StringBuffer的常用方法:
//不可变的字符序列String
//StringBuffer是可变的
//他们的方法都是一样的
append()在字符串后面追加字符;
length()查看字符串的长度;
setLength(10)设置字符串的长度为10;
indexOf();索引字符串的位置
lastindexOf();
insert(1,"2")把指定的字符串添加到指定位置
delete(1,2);删除的时候为左闭右开,删除该范围内的字符串
deleteCharAt(1);删除指定位置的数据
setCharAt(1,"2")设置指定位置的字符;
效率测试:
long start = System.currentTimeMillis();
1ong end = System.currentTimeMillis();
System.out.println( "testString用时:"+(end-start));
内存分析:
集合:存储多个数据的长度不固定
数组:数组的长度是固定的
Collection
List:
有序:添加的顺序
不唯一:可以添加重复的元素
ArrayList
数组
LinkedList
链表
set:
无序不是按照添加的顺序输出
唯一不可以添加重复元素
HashSet:无序 唯一
LinkedHash:有序:添加有序
唯一:元素唯一
SetTreeSet:有序:自然顺序
唯一“元素唯一
public void test(){
Collection a = new ArrayList();
a.add(12);
a.add(new Date());
System.out.print1n("---"+a.siae);
}
Collection的常用方法:
add(添加元素的)会将一个集合作为一个元素处理
addALL(添加集合)会将集合中的每一个元素进行单独处理
size();判断集合内有多少数据
contains();判断指定元素是否在集合内
remove();删除集合内的指定元素
removeAll();删除集合
isEmpty();判断集合是否为空
clear();清除集合内所有的数组
迭代器遍历集合:
//创建一个迭代器
Iterator iterator = c1.iterator();
//hasNext():判断游标/光标的后面是否还有数据有===> true无--->false
//next():拿到指定的数据
while(iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
增强for循环:
for(Object obj:a){
}
泛型:规定你输入的数据类型
Collection<引用数据类型>
Collection<String> c2=new ArrayList<>();
ArrayList的常用的方法:
add()添加元素,可以在指定位置添加元素
addALL(2,a)添加对象
get()通过下标获取指定元素
contains()
remove()删除指定位置的数据,或者删除指定下标的元素
set(1,"1")修改指定下标的元素
size()查看长度
isEmpty()是否为空
clear()清除列表的元素
subList()获取一个子集合[开始下标,结束下标)
indexOf()返回指定元素最后一次出现的下标
index()返回指定元素第一次出现的下标
//new String[]{} 类型数组对象,把列表转换为数组
String[] array = list.toArray();
遍历方法:
for循环,增强for循环,迭代器遍历,
listIterator:可以实现从后向前遍历
前提是需要先从前向后遍历,将光标放到最后
//创建ListIterator
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()){
String ele = listIterator.next();
System.out. print1n("1istIterator从前向后:"+ele);
}
//判断是否有前一个
while(listIterator.hasPrevious()){
String ele = listIterator.previous();//获取前一个数据
System.out-print1n("listIterator从后向前: "+ele);
}
while(listIterator.hasNext()){
System.out.println("listIterator.previousIndex() = " + listIterator.previousIndex());
String ele = listIterator.next();
System.out.print1n("1istIterator从前向后:"+ele);
System.out.println("listIterator.nextIndex()= " + listIterator.nextIndex());
}
//多态
Set<String> set = new HashSet();
HashSet的常用方法:
与Collection一样
TreeSet
class SortOfStudent implements Comparator<Student>//添加后不用进行向下转型 {
SortOfStudent sortOfAge = new SortOfStudent();
Set<Student> set = new TreeSet<>(sortOfAge); //Comparator c =sortOfAge;父类的引用指向子类的对象
Map:存储数据
存储键值对
HashMap 1.key:是无序唯一的
2.当key重复的时候会替换掉原有的旧值
3.value是可以重复的
LinkedHashMap:1.key是有序的 添加顺序
2.value:满足泛型即可
TreeMap:key有序:自然顺序
value:可以重复
public void test01(){
Map<Integer,String> map = new HashMap<>();
map.put(1,"张三");
map.put(2,"李四");
}
HashMap的常用方法:
size()//当前map集合内键值对的数量
replace(1,"1")替换指定的value
remove(1)删除指定key的键值对
获取所有的key
Set<String> set = map. keySet();
for (string s : set){
System.out.println(s+" :==>"+ map.get(s));
}
System.out-println(map);
//判断 map.containsKey()指定的键在不在map内
//判断map.containsValue()指定的value在不在map内
map.entrySet()获取的就是键值对
此时这个set内包含当前Map所有的键值对
先拿到一个一个键值对,在遍历set
Set<Map. Entry<String,String>>set = map.entrySet();
Iterator<Map.Entry<String,String>> iterator = set.iterator();
while (iterator.hasNext()){
//键值对
Map.Entry<String,String>entry = iterator.next();//获取 key
获取value
System.out.println(entry.getKey()+" ====>"+entry.getValue());
}
Set<String> set1 = map.keySet();
for(String key: set1){
System.out-print1n(key+" ---》"+map.get(key));
}
//倒叙不是进行排序
Collections.reverse(list);
//洗牌打乱顺序
Collections.shuffle(list);
//统计指定元素在集合内出现的次数
int count = Collections.frequency(list,"1");
集合的复制
Collections.copy(目标集合,数据源集合);
使用时注意目标集合的长度>=数据源集合长度否则报错
//将指定的元素按照下标进行交换
collections. swap(destList, 0,2);
//返回的集合不能修改
List<String> strings =Collections. unmodifiablelist(list);
泛型:规定你输入的数据类型
泛型:类型化参数
想到实参和形参
泛型的好处:
1.可以节约代码
2.可以让代码的可读性更强
相关的名字:
T: type类型
E: ELement 元素
K: key
V: value
Map<K,V>
不同的字母代表为了见名之意都是代表类型未知
- GenericArrayType:泛化的数组类型,即T[]
- ParameterizedType:参数化类型,例如: Comparator<T>,Comparator<String>
- TypeVariable: 类型变量,例如:Comparator<T>中的T,Map<K, V>中的K , v
- wildcardType:通配符类型,例如:Comparator<?>等
接口上泛型接口
public interface List<E>
方法上泛型方法
当方法真正执行的时候, 才确定是什么类型
public static <T> boolean addAll(Collection<? super T>c, T... elements){}
注意:泛型方法的泛型声明放到了返回值之前
类上 泛型类 Arraylist<Integer>
LinkedList
泛型的上限:
T extends Number & Comparable<T>
T:既是 Number的孩子也是Comparable的孩子
指定了T的上限:类型范围不能超过父亲
class SumTools<T extends Number & Comparable<T>>{
private T t1;
private T t2;
public SumTools(T t1,T t2){
this.t1 = t1;
this.t2 =t2;
}
public T getSum(T t1,T t2){
Integer value = Integer
}
}
泛型擦除:
1.当一个泛型类或者泛型接口没有指定类型则使用提升为0bject类型进行处理
2.局部变量的泛型在编译后会消失
方法形参成员变量泛型不会消除
泛型方法:
类型通配符:
? :带表任意类型
有位置要求
需要传入具体类型的位置不能单独使用?
声明,泛型类,泛型接口,泛型方法时不能单独使用
? extends T:你传入的类型可以是当前类型以及当前类型的孩子
? super T:传入的类型可以是当前类型也可以是当前类型的父类
泛型限制:
? :当使用?作为泛型的时候,只能传入nuLL值
无法确定孩子是哪一个只有null是确定的
都是number的孩子以及number
<? extends 上限> ?<=上限
MyClass<? extends Number> myclass1 = new MyClass<>();
<? super 下限> ?>=下限
都是number的父亲
MyClass<?super Number> myClass2 = new MyClass<>();
一般不会写这样的方法。
Vector
Vector是jdk早期的集合实现类
线程安全的synchronized
在创建Vector时数组的长度就已经指定10
当容量不足的时候进行扩容如果 capacityIncrement不是0则增长为
原有容量+capacityIncrement
如果capacityIncrement是0则增长为原来的2倍
ArrayList
创建ArrayList对象的时候
底层是空的数组是线程不安全的
扩容到原来的1.5倍
共同点:
都是采用object[]数组存储数据
>> 右移 <<左移 二进制
右移一位除以2
左移一位乘以2
system.out.print1n(6<<1) 12 有几位除几次
动态数组:
自定义集合:
LinkedList的新增方法:
addFirst()在开头增加
addLast()在末尾增加
removeFirst()返回被删除的元素
getFirst()取头部元素
getLast()去尾部元素
hash表:顺序表+链表 1.7
File:
//File file = new File("E:/2.txt");
length()
getName()
getPath()
lastModified() System.out.println(new Date(1605597516709L).toLocaleString());
getPath():构建路径相对路径
getAbsolutePath():获取绝对路径
getCanonicalPath():获取规范路径
delete()//删除的内容不经过回收站慎用
creatNewFiile()//新建一个文件创建成功返回true
mkdirs()可以参加多层目录
isFile()判断是否是文件
isDirectory()判断是否是文件夹
io流:
作用:实现数据的传输
io分类:
按照流向分:
输入流,输出流
按照传输的数据:
字节流:
文本视频图片doc. . .
字符流:
【纯】文本 doc
按照出来单元的不同:
节点流:直接怼到数据上的流节点流
inputStream outputStream
Reader writer
处理流:对节点流再次进行处理处理流
BufferedInputStream BufferedOutputStream
BufferedRead Bufferedwriter
字节流:所有的数据都可以采用字节流进行传输
--字节输入流
InputStream--字节输出流
1. OutputStream抽象类需要借助子类实现功能
可以将数据写到磁盘上还可以进行网络传输
2. FileOutputStream()直接作用到文件上是一个节点流
3.使用FileOutputStream写出数据时会将原有数据清空保留写出的数据
4.使用FileOutputStream写出数据时如果目标文件不存在的直接创建一个文件
5.os.write(写出数据的数组,开始下标,写出的数量);
6.在原有数据后进行追加
append : true可以进行追加
FiLeOutputStream(“路径", boolean append);
7.写出字符串
byte[] b=|字符串对象.getBytes();
OutputStream os = new FileOutputStream("E:/e.txt", true);
字节输出流:
InputStream抽象类通过子类FileInputStream 实现功能
1.创建字节输入流对象
File file = new File("E:/ a.txt" );
InputStream is = new FileInputstream(file);
InputStream is1 = new FiLeInputStream( "e:/ a.txt");
2.读取数据
输入流对象.read();//获取对应字符的编码值
当读到-1的时候文件内的资源已经读取完毕。
3.注意:
一次读取一个字节不能一次读一个汉字可以使用字节数组完成
byte[] b = new byte[20];
int len = 0;
//循环读取数据
while((len = is.read(b))!=-1){
}
字符输出流:
writer抽象类Filewriter
一次输出一个字符
注意:
1.字符输出流内部有一个缓冲区写出数据时先将数据写到缓冲区内
2.将数据写到磁盘中
字符输出流对象.flush();
关闭资源也会将缓冲区的数据刷出到磁盘上
Writer writer = new FileWriter()
writer.write();
writer.flush();
字符输入流:
Reader抽象类通过子类来实现功能
Reader reader = new FileReader(new File( pathname: "e:/w.txt"));
Reader reader1 = new FileReader( fileName: "E:/w.txt");
//读取char类型的数组时返回数组内有效元素的个数
read = reader.read(c);
System.out.print1n("--->" +read);
int len = 0;
while((len = reader.read(c))!= -1){
String s= new String(c,offset:0,len);//输出数据
System.out.println(s);
}
//3.关闭资源
reader.close();
文本文件的复制:
public class CopyTest i
public static void main(String[] args){
Reader reader = null;
writer writer = null;
try{
//1.创建输入输出字符流对象
reader = new FileReader("E:/作文.txt");
writer = new Filewriter("D:/作文.txt");
//2.读取数据
char []= new char[ 20];
int len = 0;
whlie ((len = reader.read(c))!=-1){
//将字符数组的数据进行写出
writer.write(c,0,len);
}
writer.flush();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}fina1ly {
if(writer!=nu11){
try {
writer.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
字节缓冲流:
使用字节缓冲输入输出流复制文件
public class BuffereCopy{
public static void main(String[] args)throws FileNotFoundException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream( name: "D:/a.mp4"));
//读取数据
long startTime = System.currentTimeMillis();
创建字节数组提高读取速度,可以提高数组的容量;
byte[] bytes = new byte[1024*20];
int len= 0;
while((len=bis.read(bytes))!=-1){
bos.write(bytes, off:0,len);
}
System.out.print1n("复制完毕");
long endTime = System.currentTimeMillis();
System.out.print1n("用时"+(endTime - startTime));
//关闭资源
bis.close();
bos.close();
}
缓冲字符流:
--缓冲字符输入流
BufferedReader
底层有一个char类型的数组存储 缓冲的数据 8192
br.readLine();一次读取一行数据当么有数据时返回null
--缓冲字符输出流
Bufferedwriter
底层有一个char类型的数组存储缓冲的数据8192
bw.newLine();新建一行
转换流:
将字节流转换为字符流 没有字符转字节
InputStreamReader()
OutputStreamWriter
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(reader);
System.out.println("请您输入数据”);
String s =br.readLine();
System.out.println(s);
OutputStreamwriter writer = new OutputStreamwriter(System.out);
writer.write( str:"你好");
writer.flush();
writer.close();
FileOutputStream stream = new FileOutputStream( name: "E:/oo.txt");
OutputStreamwriter w = new OutputStreamwriter(stream,charsetName: "GBK");
w.write( c:97);
w.close();
数据流:
可以保留数据的原始特性 int
以二进制的形式存储数据
public void test01( throws IOException i
//新建数据流对象
DataDutputStrea dos = new DataOutputStream(new FileOutputStream( name: "E:/d.txt"));//写出数据
dos.writeInt(10);
dos.writeBoolean(false);
dos.writeUTF("你好");//关闭资源
dos.close();
}
public void test02(( throws IOException {
//1.新建数据输入流对象读取数据
DataInputStream dis = new DataInputStream(new FileInputStream(name:"E:/d.txt"))
int i =dis.readInt();System.out.println(i);
boolean b =dis.readBoolean();
System.out . println(b);
String s = dis.readUTF();
System.out.println(s);
//3.关闭流
dis.close();
}
对象流:进行对象的存取
--对象输出流
objectOutputStream
--对象输入流
objectInputStream
序列化:如果将一个对象进行存储或者网络传输那么要将此对象进行序列化
如何实现序列化:实现此接Serializable
会将对象数据采用二进制的形式存到磁盘上
反序列化:将对象从磁盘或者网络中读取出来反序列化
class Person implements Serializable {
}
注意:
1.如果有属性不想进行序列化可以选择在属性前+ transient,8P的U一
2.static 修饰的属性不会参与序列化
3.在进行序列化或者反序列化序列化的版本必须一致
private static final long serialVersionUID = 2L;
4.在进行反序列化时对象类的cLass文件不能消失必须存在
使用此接口 Externalizable 也可以进行序列化和反序列化操作
序列化时会调用此方法
public void writeExternaL(objectOutput out) throws IOException}
反序列化时会调用此方法
public void readExternaL(ObjectInput in) throws IOException,ClassNotFoundException {}
使用此接口 任意属性都可以被序列化
打印流:
Printstream()
System.out 默认输出到控制台
System.err默认输出到控制台
可以通过System.setOut(打印流);改变流向
可以通过System. setErr(打印流);改变流向
Scanner的其他用法
public void test02(){
Scanner in = new Scanner(System.in);
String next = in.next();
System.out.println(next);
}
public void test03() throws FileNotFoundException {
Scanner in = new Scanner(new File( pathname: "E:[2021javaprojectllday0600P1\[src\|Student.java"));
while (in.hasNextLine()){//看是否有下一行
String s = in.nextLine();
System.out.println(s);
}
in.close();
}
try(
需要失闭资源的对象){
}catch(){
}
只要实现了此AutoCLoseable 接口就可以使用try-with-resourse新特性
jdk1.7提出
网络编程:
网络编程三要素:
获取ip地址:
win:ipconfig
linux:ifconfig
InetAddress()
/获取本地的主机名和ip地址
InetAddress in = InetAddress.getLocalHost();
System.out.print1n(in);//获取的是主机名以及端口号
String hostName = in.getHostName();
System.out.print1n("hostName = " +hostName);
String address = in.getHostAddress();
System.out.println("address =" + address);
InetAddress address = InetAddress.getByName("wwnww . baidu.com");
单向通信:
public c1ass Server {
public static void main(String[] args) throws IOException {
System.out.println("===========服务端=========");
//1.创建服务端socket对象
ServerSocket serverSocket = new ServerSocket( port:8888);
//2.获取来连接的客户端sockt对象
Socket socket = serverSocket.accept();//接受
system. out-println("来连接了....... ");//3.获取输入流对象
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(is);
//4.取出数据
String s =dis.readUTF();
System.out-println("客户端发来了消息:1t"+s);
//5.尖闭资源
dis.close();
serverSocket.close();
}
}
public class Server {
public static void main(String[] args)throws IOException {
System.out.print1n("=========服务端========");
//1.创建服务端socket对象
ServerSocket serverSocket = new ServerSocket( port:8888);//2.获取来连接的客户端sockt对象
Socket socket = serverSocket.accept();//接受线程阻塞
System.out-println("来连接了....... ");
//3.获取输入流对象
InputStream is = socket.getInputStream();
DataInputStream dis =new DataInputStream(is);
//4.取出数据
String s =dis.readUTF(O);
System.out-print1n("客户端发来了消息");
//5.尖闭资源dis.close();
serverSocket.close();
}
}
双向通信:
public class Server {
public static void main(String[] args) throws IOException {
//1.创建服务端对象
ServerSocket serverSocket = new ServerSocket( port: 9999);
//2.获取对用的客户端socket
Socket socket = serverSocket.accept();
/ /3.获取输入流
InputStream is = socket-getInputStream();//将字节流变为字符流
InputStreamReader reader = new InputStreamReader(is);/将字符流-->缓冲字符流
BufferedReader br = new BufferedReader(reader);
/ /4.读取客户端发来的消息
String s = br.readLine();
System.out.println("客户端发来的消息:"+s);
}
}
public static void main(String[] args) throws IOException {
System.out.println("===============服务端=========:");
//1.创建服务端对象
ServerSocket serverSocket = new ServerSocket( port: 9999);
//2.获取对应的客户端的socket对象
int count = 1 ;
while (true){
Socket socket = serverSocket.accept();
String hostName = socket.getInetAddress().getHostName();
System.out.println(hostName +"来连接了,您是第["+(count++)+ "]个连接的");
SocketThread thread = new SocketThread(hostName,socket);
//后动线程
thread.start();
}
}
}
1class SocketThread extends Thread{
private Socket socket;
pub1ic SocketThread(String name,Socket socket) {
super(name);
this.socket = socket;
}
@Override
public void run(){
try(
//1.接收客户端的信息输入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));/l2.向客户端反馈消息输出流
PrintStream ps = new PrintStream(socket.getOutputStream());
){
//3.使用循环不停的接收消息
String mess = "";
while ((mess=br.readLine())!=nu11){
System.out.print1n("客户端【"+name+”】发来的消息" + mess);
StringBuilder sbl = new StringBuilder(mess);
sbl.reverse();
//5.返回给客户端
ps.println(sbl.toString());
}
}catch (IOException e){
e.printStackTrace();
}
}
UDP网络编程:
DatagramSocket:客户端/服务端
DatagramPacket:数据包
public class Client {
public static void main(String[] args) throws IOException {
//1.新建客户端对象
DatagramSocket ds = new DatagramSocket( port:9999);
//1.1准备数据包
String mess =“您吃了吗";
byte[] bytes = mess.getBytes();
//数据 目的地 ip地址 端口号
DatagramPacket packet = new DatagramPacket(bytes,bytes.length,InetAddress.getLocalHost(), port: 8888);//2.发送数据
ds.send(packet);
}
}
public c1ass Server {
public static void main(String[ ] args)throws IOException {
System.out.print1n("--------Server--------—");
//服务端
DatagramSocket dsServer = new DatagramSocket( port: 8888);
//淮备数据包
byte b[]= new byte[ 1024*20];
DatagramPacket packet = new DatagramPacket(b,b.length);
//接收数据
dsServer.receive(packet);
//有效数据的个数
System.out.println("packet.getLength()= " + packet.getLength());
//获取发送数据包的客户端的端口号
System.out.println("packet.getPort()=" + packet.getPort());
//获取客户端的地址
System.out.println("packet.getAddress()= " + packet.getAddress());
//获取发送过来的数据
System.out.println("packet.getData()= " + packet.getData());
System.out.println("packet.getData()= " + Arrays.toString(packet.getData()));
String s = new String(b, offset:0,packet.getLength());
System.out.print1n(s);
}
}
UDP双向通信:
public class Server {
public static void main(String[] args) throws SocketException f
System.out.println("====E=============服务端=================")
//1.创建服务端对象
DatagramSocket dsServer = new DatagramSocket( port: 8888);
//2.准备数据包
byte[] bs = new byte[1024];
DatagramPacket packet = new DatagramPacket(bs,bs.length);
//3.接收数据
dsServer.receive(packet);//4.输出数据
String s =new String(bs,offset:0, packet.getLength());System.out.println("客户端发来的数据:"+s);
//5.返回数据给客户端
byte[] bytes ="鹅鹅鹅".getBytes();
/客户端发来的数据包中有客户端的ip地址和端口号
DatagramPacket sendPacket = new DatagramPacket(bytes,bytes.length,InetAddress.getlocalHost(),packet .getPort());
//6.将数据发送给客户端
dsServer. send(sendPacket);
}
}
public class Client {
public static void main(String[] args)throws IOException {
System.out.println("------客户端------");
// 1.创建客户端对象
DatagramSocket ds = new DatagramSocket();1/2.准备数据包
byte[] bytes =“睡醒没有”-getBytes();l
DatagramPacket packet = new DatagramPacket(bytes, bytes.length,InetAddress.getLocalHost(),port:888);//3.发送数据包
ds.send(packet);
byte[]b = new byte[ 1024];
DatagramPacket recivePacket = new DatagramPacket(b, b.length);
ds.receive(recivePacket);
//输出服务端反馈给客户端的信息
System.out.println(new String(b,offset: 0, recivePacket.getLength()));
}
}
反射:Reflect
类的加载:
1.当使用类中的静态常量的时候不会触发类的初始化因为在类的加载阶段完成了对静态常量的赋值
2.当子类使用从父类继承过来的静态方法时只会对父类完成类的初始化子类不会进行初始化
3.创建一个类型的数组时不会触发对该类的初始化
1.调用该类的main() 会 导致该类完成初始化
2.当创建子类对象时 会 先进行父类的初始化
3.使用类中的静态资源时 会 进行类的初始化
4.创建一个类的对象时 会 进行该类的初始化
5.使用反射操作此类时 会 进行该类的初始化
双亲委托:
先由当前类加载器查看是否加载过这个类如果没有加载过
父类加载器会查看是否加载过这个类继续向上传递
根加载器没有加载过这个类 ClassNotFoundException
javalang.Class类
类型获取class对象的四种方式:
class Person{};
1. Class<Person> personClass = Person.class;
2. Person p1 = new Person();
Class aClass2 =p1.getClass();
3. Class aClass3 = aClass2.getClassLoader().getClass();
4. Class aClass4 = class.forNgme( "com.atguigu.reflect.clazz.Person");
class的作用:
//Nethod[] decLaredNethods = clazz.getDeclaredMNethods();//只能获取本类中的方法私有
//不仅可以获取本类中 public的方法也会拿到父类中public的方法
Method[ ] declaredMethods = clazz.getMethods();
使用反射创建对象:
//1.获取对应的CLass对象
Scanner in = new Scanner(System.in);
System.out.print1n(“请输入你要创建对象的全类名");
String className = in.next();
Class clazz = Class.forName(className);
//2.创建对象了调用了对应类型的无参构造器
Object o = clazz.newInstance();
System.out.println(o);
//1.获取CLass对象
Class clazz = Class.forName("com.atguigu.createobject.Student");
//2.获取构造器
//获取一个参数的构造器放的是参数的CLass
Constructor constructor = clazz.getConstructor(String.class);
//3.执行构造器
object instance = constructor.newInstance( ...initargs:“杜甫");
//4.输出结果
System.out.print1n(instance);
//获取的构造器非public要使用 getDecLaredConstructor
Constructor c = clazz.getDeclaredConstructor(String.c1ass,int.class);
//设置私有的构造器可以访问的
c.setAccessible(true);
使用反射操作私有属性:
//静态变量可以不用创建对象直接使用
//1.获取CLass对象
Class clazz = Class.forName("com.atguigu.fie1d.Person");
//2.获取属性
Field country =clazz-getField("country");
//4.获取属性值
object o1 = country.get(nu11);
//5.输出属性值
System.out.println(o1);
public void test03() throws Exception{
//1.获取cLass对象
Class clazz = Class.forName( "com.atguigu.fie1d.Person");
//2.获取私有的属性
Field name = clazz.getDeclaredField(name: "name");
//设置私有属性可见
name. setAccessible(true);
//3.创建对象
Object instance = clazz.newInstance();
//3.1修改属性值
name.set(instance,“范冰冰");
//4.获取属性值
0bject value = name.get(instance);System.out.println(value);
利用反射操作方法:
静态的方法可以不用创建对象直接调用
非静态方法必须创建对象调用
私有方法要设置私有方法可见
method.setAccessible(true);
public void test03( throws Exception ){
//1.获取CLass对象
Class clazz = Class.forName("com.atguigu.method.Person");
//2.获取方法名
clazz-getDeclaredMethod("showMessage");
//3.创建对象
//4.执行方法
利用反射获取注解:
Class clazz = Class.forName( "com.atguigu.ann.Person");//获取所有的注解
/ *Annotation[] annotations = cLazz.getAnnotations();
for (Annotation annotation : annotations){
System.out.printLn(annotation);
}*/
Annotation annotation = clazz.getAnnotation(MyAnn.c1ass);
System.out.print1n(annotation);
利用反射突破泛型限制:
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
// list.add(new Data());
Class clazz = list.getclass();
Method addMethod = clazz.getDeclaredMethod( name: "add", Object.c1ass);
addMethod.invoke(list,new Date());
addMethod.invoke(list,new Person());
System.out.print1n(list);
实验反射创建数组:
//创建了一个数组长度是5
object o = Array.newInstance(String.c1ass,length: 5);
//int [];
System.out.print1n(o);
Array.set(o, index:0,value:"李白");
Array.set(o,index: 1,value:"杜甫");
0bject o1 = Array.get(o,index: 1);
@FunctionalInterface
检验当前的接口是不是函数式接口
只能有一个抽象方法
知道的函数式接口:
Runnable
Comparator
函数式接口:
接口内的方法没有任何参数
():看一下要重写的方法有没有参数
->:Lambda的一个标识
:代表了当前方法体重写方法要做的内容
()->{System.out.println("哈哈哈");}
/*
show(a, b, new Calc() {
@Override
public int add(int a, intb){
return atb;
}
});*/
show(a, b,(int c1, int d1)->{
return c1 +d1;
})
} 可以省略形参的类型
/*show(66,88,(c1,d1)->{
return c1 +dl;
});*/
//当方法体只有一局代码的时候则可以省略return
show( a: 60,b:8o,(c1,d1) ->c1 +d1);
static void show(int a,int b, calc c){
int add = c.add(a,b);
System.out. println(add);
}
}
interface Calc {
int add(int a, int b);
}
消费型接口:
功能型接口:
Supplier<String>s =new Supplier<String>(){
@Override
public String get({
return"你好
}
};
System.out.println(s-get());//当没有形参的时候不能省略
Supplier<String> s1 =()->"你好啊";
System.out.println(s1.get());
Stream.generate(()->Math.random()).forEach((a)->5ystem.out.println(a));
方法引用:
//Stream.generate(()->Math.random()).forEach(System.out::println);
Stream.generate(Math::random).forEach(System.out::println);
方法引用的语法格式:
(1)实例对象名::实例方法
(2)类名::静态方法
(3)类名::实例方法
构造器的引用:
语法格式:
类名new
数组类型名:new
public void test01(){
/*Supplier<EmpLoyee> e = new Supplier<EmpLoyee>() i
@Override
public Employee get()i
return new Employe();
}
};*/
Supplier<Employee>e =Employee::new;
System.out.println(e.get());
}
创建流的方法:
Stream方法
public void test02(){
//******
int[]arr = {20,30,43,23,12};
Arrays.stream(arr).forEach(System.out: : println);
}
public void test03(){
/******
Stream.of(10,20,30,56).forEach(System.out : :println);
}
Stream.iterate(1, new UnaryOperator<Integer>() {
@override
public Integer appLy(integer integer){
return 10;
}
}).forEach(System.out: : println);*/
//Stream.iterate(1,(t)->t t= 1). forEach(System.out : : println);
Stream.generate(Math: :random) . forEach(System.out: :println);
中间操作:可以存在多个
distinct去除重复的元素
long count = Stream.of(10,20,30,1,1,2,3,4, 5, 7).filter((s) ->5 % 2 != 0).count()
peek()
终结操作:只能有一个
//allMatch所有的元素是不是都是10
//anyMathch
//NoneMath
boolean b = Stream.of(1,20,30,1,1,2,3,4,5, 7).anyMatch((s)->s == 10);
collect:将满足要求的数据进行收集
Optional:
public void test02(){
Student s1 = new Student();
Optional<String> name = getName(s1);
System.out.print1n(name.orElse( other:“张三"));
}
public static Optional<String> getName(Student s){
return Optional.ofNulLable(s.name);
}
jQuery库:
<!--导入jQuery库-->
<script type="text/javascript" src="script/jquery-1.7.2.js"></script>
<script type="text/javascript">
//调用jQuery库定义的函数
//使用$()代替window. onload
$(function(){
//根据id属性获取按钮对象,并绑定单击响应函数
$("#btnId").click(functionO{
//弹出He11owor 1d
alert("He11owor1d");
});
});
</script>
XML:

浙公网安备 33010602011771号