java
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IcSAfksE-1677633758950)(D:\桌面\bug集\扩展\typora-img\image-20220925131548704.png)]
成员变量:在使用前都经历过默认初始化赋值
- 类变量(静态变量):先默认赋值在显示赋值
- 实例变量:随着对象的创建,会在堆空间中分配实例变量空间,并进行默认赋值
局部变量:在使用前,必须要进行显示赋值!否则,编译不通过。
a++的值为a
++a的值为a+1
数组的扩容:就是让源数组的length+1、实现扩容
继承中
成员变量使用:变量中就近原则
成员方法使用:子类可以使用父类的所有非私有功能
构造方法使用:
构造方法可以被继承吗?答案是不可以
原因:由于构造方法的语法要求,构造方法必须与类同名,
不能再子类有一个父类名字的构造方法,天然不符合要求;
构造方法不可以被调用而是由系统创建的时候调用
在子类的构造方法中,默认存在super(),表示调用父亲的无参构造
也就是说,在创建子类对象时,会去调用子类的构造方法,继承后
会先调用父类的构造方法,再去调用子类的构造方法
多态
多态是为了统一调用标准,向父类看齐;不可调用子类的特有方法;成员变量的使用都是父类的;方法的声明看的是父类,实际使用的是子类的;如果子类中有同名的静态方法,使用的是父类的
抽象类与接口
在Java中被abstract关键字修饰的类称为抽象类,被absffact关键字修饰的方法称为抽象方法,抽象方法只有方法的声明,没有方法体。
抽象类的特点:
1.抽象类不能被实例化只能被继承;
1.抽象类不能被实例化,所以抽象类必须被继承,才能被使用。
2.抽象类也可以和类一样,实现接口、多接口等,但抽象类区别于类,不需要实现接口下的所有方法。用途:例如需要一个类,但是不需要有具体执行的代码,那么就可以把这个类写成抽象类。
3.抽象类(Persion)被子类(Man)继承后,就会强迫子类重写抽象类中定义的抽象方法,除非子类也是抽象类。
2.包含抽象方法的一定是抽象类,但是抽象类不一定含有抽象方法;
3.抽象类中的抽象方法的修饰符只能为public或者protected,默认为default;
4.一个子类继承一个抽象类,则子类必须实现父类抽象方法,否则子类也必须定义为抽象类;
5.抽象类可以包含属性、方法、构造方法,但是构造方法不能用于实例化,主要用途是被子类调用。
Java代码行执行顺序:1.静态块:用static声明,JVM加载类时执行,仅执行一次2.构造块:类中直接用D定义,每次创建对象时执行3.执行顺序优先级:静态块>main()>构造块>构造方法4.静态块和静态属性优先执行,谁在前先执行谁。
父类静态代码块》子类静态代码块》父类构造代码块》父类构造器》子类构造代码块》子类构造器
接口
Java中接口使用interface关键字修饰,特点为:
1.接口可以包含变量、方法;变量被隐士指定为public static final,方法被隐士指定为public abstract(JDK1.8之前) ;
2.接口支持多继承,即一个接口可以extends多个接口,间接的解决了Java中类的单继承问题;
3.一个类可以实现多个接口;
- JDK1.8中对接口增加了新的特性:
(1)、默认方法(default method): JDK 1.8允许给接口添加非抽象的方法实现,但必须使用default关键字修饰;定义了default的方法可以不被实现子类所实现,但只能被实现子类的对象调用;如果子类实现了多个接口,并且这些接口包含一样的默认方法,则子类必须重写默认方法;
(2) 、静态方法(static method): JDK 1.8中允许使用static关键字修饰一个方法,并提供实现,称为接口静态方法。接口静态方法只能通过接口调用(接口名静态方法名)。
抽象类可以有默认的方法实现完全是抽象的。接口根本不存在方法的实现。抽象类中可以有已经实现了的方法,也可以有被abstract修饰的方法(抽象方法),因为存在抽象方法,所以该类必须是抽象类。但是接口要求只能包含抽象方法,抽象方法是指没有实现的方法。
相同点
1.接口和抽象类都不能被实例化,主要用于被其他类实现和继承。
2.接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
不同点
1.接口只有定义,不能有方法的实现,JDK 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
2.实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
3.接口强调特定功能的实现,而抽象类强调所属关系。
4.接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public,abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private,static,synchronized和native等修饰,必须以分号结尾,不带花括号。
BIO流 阻塞:就是代码里面某个线程卡住了就是阻塞现象
字节流 OutputStream、InputStream(以字节为单位)
文件流 new FileOutputStream("bbb.txt"); 创建之后回先删除文件里的所有内容、之后无论写入几次都会成功;
new FileOutputStream("bbb.txt",true); 会保留文件原有的数据,之后进行写操作不会删除之前的数据
new ByteArrayOutputStream(); //ByteArrayOutputStream 对byte类型数据进行写入的类 相当于一个中间缓冲层,将类写入到文件等其他outputStream。它是对字节进行操作,属于内存操作流
节点流:又称低级流,负责进行读写数据
处理流:又称高级流,不能独立存在,必须连接在其他流上,目的是对数据进行处理简化我们的操作
缓存流 作用是加快读写效率
BufferedInputStream、BufferedOutputStream
缓存流会有一个缓存区,需要调用flush()来处理缓存数据(其他流的这个方法只是做一个调用,真正干活的还是缓存流)
字符流 Reader、Writer(以char为单位)
转换流 OutputStreamWriter、InputStreamReader
ByfferedWriter BufferedReader 缓存字符流 增加字符读写效率
//主要流连接用法
OutputStream out = socket.getOutputStream();//获取流
OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);//字节转字符、字符转字节
BufferedWriter bw = new BufferedWriter(osw);//缓存输出流
PrintWriter pw = new PrintWriter(bw,true);//默认刷新缓存
NIO (通道)非阻塞Io(读写过程中不会发生阻塞线程)
非阻塞IO面向Channel("通道")的,不是面向Stream(流)的。
流的特点:方向单一,顺序读写。流要么是输入流用于顺序读取数据,要么是输出流用于顺序写出数据
Channel(通道)的特点:双向的,既可以读又可以写。
Filechannel:文件通道,
SockentChannel:套接字通道,对远端进行TCp读写操作
ServerSocketChannel:服务端的套接字,监听客户端
Buffer缓冲区,通道是对缓冲区中的数据进行读写操作
ByteBuffer:字节缓冲区
/**读前
* position() 0
limit() 10240
*/
缓冲区读写是根据于 position() -limit() - 来进行缓存大小,来决定你下次能不能读到数据
如果设定的容量是byte[1024*10]并且缓冲区已经读满了,就无法读到数据了
/**读后
* position() 10240
limit() 10240
*/
总结Channel通道在进行读或写操作时,具体可以读取多少个字节或写出多少个字节是取决于我们传入的ByteBuffer中position到Llimit之间的空间。
while ((len=inChannel.read(buf))!=-1){
buf.flip();//反转内容
outChannel.write(buf);
buf.clear();//清空缓冲区内容
}
异常
try{
}catch(){
}finally{//不管对错都会执行一次
}
throw 1)程序正常不满足业务;2)真的出错了抛出异常
throws 1)就相当于提前说会出错,让做好出错的解决办法
多线程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HtgVVxLM-1677633758951)(D:\桌面\bug集\扩展\typora-img\image-20221002165941516.png)]
新建- 可运行状态- 运行状态- 阻塞状态 - 死亡状态
继承Therad、实现Runnable、实现Clouber
当线程在sleep()状态下,被某个线程调用interrupt();方法时会导致在sleep状态下的线程提前醒来
守护线程:是通过普通线程调用setDaemon(true)设置的。(守护普通线程、共同死亡)
public void buy(){
try {
Thread thread = Thread.currentThread();
System.out.println(thread.getName()+"挑衣服");
Thread.sleep(3000);
//同步块使用时需要指定一个同步监视器对象、既:上锁的对象
该对象从语法的角度来讲可以是任意引用类型的实例。但是必须同时满足多个需要同步执行该代码片段的线程看到的是同一个对象才可以
synchronized (this){
System.out.println(thread.getName()+"试衣服");
Thread.sleep(3000);
}
System.out.println(thread.getName()+"结账走人");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
锁静态方法一般锁的是类名.class 既:类对象
采用继承Thread类方式:
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
Runnable和Callable的区别:
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以,因为run方法本身没有抛出异常,所以自定义的线程类在重写run的时候也无法抛出异常
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
start()和run()的区别
start()方法用来,开启线程,但是线程开启后并没有立即执行,他需要获取cpu的执行权才可以执行
run()方法是由jvm创建完本地操作系统级线程后回调的方法,不可以手动调用(否则就是普通方法)
线程池(是线程管理机制)
1)复用线程
2)控制线程数量
ExecutorService executorService = Executors.newFixedThreadPool(2);//控制线程数量
for (int i = 0; i < 5; i++) {
Runnable runnable = new Runnable(){
public void run() {
Thread thread = Thread.currentThread();
System.out.println(thread.getName()+"接任务");
try {
Thread.sleep(5000);
System.out.println(thread.getName()+"一个任务结束了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
executorService.execute(runnable);
}
/**
* shutdown()
* 会执行完线程的内容在关闭
* shuydownNow()
* 强制中断所有线程 来停止线程池
*/
executorService.shutdown();
System.out.println("线程池关闭了");
}
集合Collection
System.out.println(Arrays.toString(list.toArray())) //list转数组
String[] myArray = { "Apple", "Banana", "Orange" };
List<String> myList = Arrays.asList(myArray);//数组转list
//迭代器
Collection v = new ArrayList<>();
v.add("1fdaf");
v.add("3adfa");
v.add("2dsaf");
//迭代器遍历Collection 一般用在超类上
核心就是在遍历集合的时候删除某个元素
Iterator a = v.iterator();
while (a.hasNext()){
Object next = a.next();
System.out.println(next);
}
c.forEach(s->System.out.println(s));//jdk8 推出的遍历方式
判断
空串 = 长度==0;
空串 = "".equals();
HasmMap
称为散列表、哈希表。是当今查询速度最快的数据结构
TreeMap:使用二叉树算法实现Map
map遍历操作 根据key返回结果进行遍历
1)Set<String> strings = map.keySet();//获取key
for (String string : strings) {
}
2) Set<Map.Entry<String, Object>> entries = map.entrySet();//获取键值对
for (Map.Entry<String, Object> entry : entries) {
entry.getKey();
entry.getValue();
}
Stream
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BCh81wL7-1677633758952)(D:\桌面\bug集\扩展\typora-img\image-20221105095015249.png)]
最基础的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t51uFxcl-1677633758952)(D:\桌面\bug集\扩展\typora-img\image-20221105095137999.png)]
反射(动态机制)
java反射机制
反射是java中的动态机制,它允许我们在程序运行期间再确定类的实例化,方法的调用,属性的调用等,而不是传统意义上的在编码期间确定。
因此,反射可以大大的提高代码的灵活度,但是随之而来的是更多的系统开销和较慢的运行速度,因此不能过度的依赖反射。
优点:
反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;
缺点:
1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。
2、使用反射会模糊程序内内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。 至于执行效率的话,还可以,因为它是一种强类型语言,执行效率不错。不过,建议将反射过后,保存进 cache中。
Class类
Class的每一个实例用于表示JVM加载的一个类,所以我们也称Class的实例 为类的类对象。 当JVM加载一个类时会同时实例化一个Class的实例与之对应,这个Class实例 中会保存该类的一切信息(类名,有哪些方法,构造器,属性,注解等等) 我们在程序运行期间通过某个类的类对象来操作这个类。因此使用反射操作某个 类的第一件事就是获取该类的类对象
获取一个类的类对象有三种方式:
- 1:类名.class 例如: Class cls = String.class; Class cls = int.class (基本类型只能通过这种方式获取类对象)
- 2:Class.forName(String className) 通过Class的静态方法forName,传入对应类的完全限定名(包名.类名)的 形式获取类对象 Class cls = Class.forName(“java.lang.String”);
- 3:通过类加载器ClassLoader加载类对象
package reflect;
import java.lang.reflect.Method;
/**
* java反射机制
* 反射是java中的动态机制,它允许我们在程序运行期间再确定类的实例化,方法的调用,
* 属性的调用等,而不是传统意义上的在编码期间确定。
*
* 因此,反射可以大大的提高代码的灵活度,但是随之而来的是更多的系统开销和较慢的
* 运行速度,因此不能过度的依赖反射。
*/
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException {
/*
Class类
Class的每一个实例用于表示JVM加载的一个类,所以我们也称Class的实例
为类的类对象。
当JVM加载一个类时会同时实例化一个Class的实例与之对应,这个Class实例
中会保存该类的一切信息(类名,有哪些方法,构造器,属性,注解等等)
我们在程序运行期间通过某个类的类对象来操作这个类。因此使用反射操作某个
类的第一件事就是获取该类的类对象
获取一个类的类对象有三种方式:
1:类名.class
例如:
Class cls = String.class;
Class cls = int.class (基本类型只能通过这种方式获取类对象)
2:Class.forName(String className)
通过Class的静态方法forName,传入对应类的完全限定名(包名.类名)的
形式获取类对象
Class cls = Class.forName("java.lang.String");
3:通过类加载器ClassLoader加载类对象
*/
//获取String的类对象
// Class cls = String.class;
/*
Class.forName()
该方法要求必须处理异常:ClassNotFoundException
当指定的字符串(对应类的完全限定名)有误时会抛出该异常,或指定的
路径下无法找到该类时也会抛出该异常(多发生于通过反射加载第三方
jar文件里的类,有时我们忘记将该jar导入环境变量中,导致JVM无法
通过正确的包路径找到它)。
*/
// Class cls = Class.forName("java.lang.String");
/*
类加载器ClassLoader
类加载器有很多中不同的实现,创建方式也各不相同。
最常用的是如下方式:
ClassLoader loader = 当前类.class.getClassLoader();
类加载器除了可以加载类对象,还可以做很多和环境变量相关的操作,功能多。
*/
ClassLoader classLoader = ReflectDemo1.class.getClassLoader();
Class cls = classLoader.loadClass("java.lang.String");
//查看类名
//获取类的完全限定名(包名.类名)
String className = cls.getName();
System.out.println("类名:"+className);
//仅获取类名
className = cls.getSimpleName();
System.out.println("类名:"+className);
//通过类对象获取其表示的类的所有方法
//获取所有公开方法和从超类继承的方法
// Method[] methods = cls.getMethods();
// for(Method method : methods){
// System.out.println(method.getName());
// }
//获取本类定义的方法(包含私有方法,但是不含有从超类继承的方法)
Method[] methods = cls.getDeclaredMethods();
for(Method method : methods){
System.out.println(method.getName());
}
}
}
使用反射机制进行对象的实例化
Class提供的方法:
Object newInstance()
该方法可以使用其表示的类的无参构造器进行对象实例化
package reflect;
/**
* 使用反射机制进行对象的实例化
*/
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Person p = new Person();//硬编码,编码期间确定实例化那个类
System.out.println(p);
/*
使用反射机制实例化
1:获取要实例化类的类对象
2:通过类对象的newInstance方法实例化
*/
//1加载类对象
// Class cls = Class.forName("reflect.Person");
ClassLoader classLoader = ReflectDemo2.class.getClassLoader();
Class cls = classLoader.loadClass("reflect.Person");
//2通过类对象实例化
Object o = cls.newInstance();//调用无参构造器
System.out.println(o);
}
}
使用有参构造器实例化对象
package reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 使用有参构造器实例化对象
*/
public class ReflectDemo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Person p = new Person("刘苍松",55);
System.out.println(p);
//加载类对象
Class cls = Class.forName("reflect.Person");
//获取无参构造器
// Constructor c = cls.getConstructor();
// Object o = c.newInstance();
//先获取指定的构造器:Person(String name,int age)
Constructor c = cls.getConstructor(String.class,int.class);
Object o = c.newInstance("刘苍松",55);
System.out.println(o);
}
}
使用反射机制调用方法
调用无参数方法:
package reflect;
import java.lang.reflect.Method;
import java.util.Scanner;
/**
* 使用反射机制调用方法
*/
public class ReflectDemo4 {
public static void main(String[] args) throws Exception {
Person p = new Person();
p.sayHello();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入类名:");
String className = scanner.nextLine();
System.out.println("请输入方法名:");
String methodName = scanner.nextLine();
//实例化
ClassLoader classLoader = ReflectDemo4.class.getClassLoader();
// Class cls = classLoader.loadClass("reflect.Person");
Class cls = classLoader.loadClass(className);
Object o = cls.newInstance();//new Person()
//调用方法
//1通过类对象获取要调用的方法
// Method method = cls.getMethod("sayHello");//获取无参方法sayHello
Method method = cls.getMethod(methodName);
//2通过方法对象执行该方法
method.invoke(o);//o.sayHello() o实际上是一个Person对象
}
}
调用有参方法:
package reflect;
import java.lang.reflect.Method;
/**
* 调用有参方法
*/
public class ReflectDemo5 {
public static void main(String[] args) throws Exception {
Class cls = Class.forName("reflect.Person");
Object o = cls.newInstance();
//say(String info)
Method m = cls.getMethod("say",String.class);
m.invoke(o,"hello~~");//p.say("hello~~")
//say(String info,int sum)
Method m2 = cls.getMethod("say",String.class,int.class);
m2.invoke(o,"嘿嘿",5);
}
}
访问私有方法:
package reflect;
import java.lang.reflect.Method;
/**
* 使用反射机制调用私有方法
*/
public class ReflectDemo6 {
public static void main(String[] args) throws Exception {
Person p = new Person();
// p.hehe();//编译不通过!
Class cls = Class.forName("reflect.Person");
Object o = cls.newInstance();
//获取私有方法:private void hehe()
// Method m = cls.getMethod("hehe");
//获取私有方法不能用getMethod,(这用来获取公开方法)
Method m = cls.getDeclaredMethod("hehe");
m.setAccessible(true);//强制访问
m.invoke(o);//o.hehe()
}
}
转发
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wLDNJpwh-1677633758953)(D:\桌面\bug集\扩展\typora-img\image-20220917082208939.png)]
实现:
在HttpServletResponse中定义一个方法:sendRedirect()
该方法中设置状态代码为302,并在响应头中包含Location指定需要浏览器重新发起请求的路径将原来Controller中内部跳转页面的操作全部改为重定向。
lambda表达式
/**
* JDK8之后java推出了一个特性:lambda表达式
* lambda可以使得程序员面向函数式编程
*
* 直观感受,可以用更精简的语法创建匿名内部类
* 但是lambda创建匿名内部类是要求所实现的接口中只能有一个抽象方法。
* 语法:
* (参数列表)->{
* 方法体
* }
*/
public class LambdaDemo {
public static void main(String[] args) {
//匿名内部类写法
FileFilter filter = new FileFilter() {
public boolean accept(File file) {
return file.getName().contains("o");
}
};
//lambda表达式写法(就是省去了接口名和方法名)
FileFilter filter1 = (File file)->{
return file.getName().contains("o");
};
//参数类型可以忽略不写,如果只有一个参数时,参数列表的"()"可以忽略不写
FileFilter filter2 = file->{
return file.getName().contains("o");
};
//当方法体中只含有一句话时,方法体的"{}"可以忽略,并且如果含有return时要一同忽略
FileFilter filter3 = file->file.getName().contains("o");
File dir = new File(".");
File[] subs = dir.listFiles(
file->file.getName().contains("o")
);
}
}
WEB知识
URL:http:+域名+访问资源
from 表单提交需要输入框里有name属性 才可传递参数
JVM
内存泄漏:不在使用的对象没有被回收机制回收,它一直占用着内存,称之为内存泄漏
内存溢出:内存泄漏持续发生,内存的垃圾对象越来越多,达到内存的上限,称之为内存溢出
GIT
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T8fPnNoR-1677633758954)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220906130719878.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FQp5Bzx6-1677633758955)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220906131236975.png)]
在项目名右击Git add 添加到本地仓库 在点击push 输入git创建好的地址 输入用户名密码 最后提交
网络
tcp 比较安全、
udp 效率快,会丢数据
http 协议字符集 是iso8859-1是欧洲字符集 不支持中文
https 是携带密钥 xal +http组成的
抓包
抓取移动端配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qd5tG2tT-1677633758956)(D:\桌面\bug集\扩展\typora-img\image-20221023152150584.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-51VVoFWN-1677633758956)(D:\桌面\bug集\扩展\typora-img\image-20221023152132703.png)]