javaSE-面向对象&核心知识总结


声明:本文是我回顾javaSE所作笔记,如有错误还请指正。另外本文参考大量博文,数量众多,无法指明原文,如有冒犯,还请见谅!

一、JVM初探

1、类的加载

类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的Java.lang.Class对象,用来封装类在方法区类的对象。

img

类的加载的最终产品是位于堆区中的Class对象。 Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。

2、类初始化

# 类什么时候才被初始化:
    1)创建类的实例,也就是new一个对象
    2)访问某个类或接口的静态变量,或者对该静态变量赋值
    3)调用类的静态方法
    4)反射(Class.forName("com.lyj.load"))
    5)初始化一个类的子类(会首先初始化子类的父类)
    6)JVM启动时标明的启动类,即文件名和类名相同的那个类 只有这6中情况才会导致类的类的初始化。

img

img

二、面向对象

1、static关键字

# static关键字:静态的
核心作用:方便在没有创建对象的情况下进行调用(方法/变量)。
	static修饰的方法/变量只能使用【类名.】的方式来调用,也可使用this(this代表当前对象)
	static修饰的都是类级别的
静态变量
	静态变量在类加载的的时候初始化。静态变量存储在方法区。如果该类的每个对象的某一属性都相同,则定义为静态变量是极为明智的,可以节省内存!静态变量的调用不存在空指针异常(类一定存在,但对象可能不存在)
静态方法
	static修饰的方法类方法,调用时使用【类名.】的形式来调用,多用于工具类
	何时使用?如果该方法执行的操作不依赖于其类的各个非静态【变量和方法】,将其设置为静态占用的内存会更小。
静态代码块
	 静态代码块在类初始化的过程执行
	 静态代码块在非静态代码块之前执行(静态代码块—非静态代码块—构造方法)。静态代码块只在第一次new执行一次,之后不再执行
	 静态代码块的执行顺序按照静态代码块的声明顺序执行
	 静态代码块中也不能使用非静态的成员变量、方法
	 何时使用?如果一些常用的对象或者属性需要在项目启动时就执行可以考虑静态代码块。静态代码块是自动执行的。如String、Array类

2、this关键字

# this关键字指向的是当前对象的引用
this关键子的作用:
	1、区分成员变量和局部变量
	2、代表当前对象
	3、构造器与构造器之间的调用(只能引用一个构造方法且必须位于首行)
//this关键字的构造方法之间的调用
public class TextThis {
   
    private String name;
    public TextThis(){
   
        this("小明");
    }
    public TextThis(String name){
   
        this.name = name;
    }

    public static void main(String[] args) {
   
        System.out.println(new TextThis().name);//结果为:小明
    }
}
	/*
	如此demo所示,创建了TextThis类,声明了两个构造方法,一带参,一无参。
	带参构造方法中将此参数赋值给类的成员变量name
	无参构造方法中使用了this关键字调用了类的有参构造方法,此句就相当于如果调用了类的无参构造方法实质调用了new TextThis("小	明")
     */

3、final关键字

# final :最终的,不可变的
	final修饰的类不可被继承
	修饰的方法不可被重写
	修饰的变量不能被改变(只能赋值一次)
	修饰的成员变量必须手动赋值,可以在【声明时】进行赋值也可以在【构造方法】中进行赋值。且只能赋这一次值。
	final修饰的成员变量一般和static联合使用,称为【常量】。常量不可变,且一般为公开的

4、抽象类和接口

# 接口

    1 因为java不支持多重继承,所以有了接口,一个类只能继承一个父类,但可以实现多个接口,接口本身也可以继承多个接口。
    2 接口里面的成员变量默认都是public static final类型的。必须被显示的初始化。
    3 接口里面的方法默认都是public abstract类型的。隐式声明。
    4 接口没有构造方法,不能被实例化。
    5 接口不能实现另一个接口,但可以继承多个接口。
    6 类如果实现了一个接口,那么必须实现接口里面的所有抽象方法,否则类要被定义为抽象类。
# 抽象类
    1 如果将一个类声明为abstract,此类不能生成对象,只能被继承使用。 
    2  抽象方法必须存在于抽象类中。
    3  抽象类中可以有一般的变量和一般的方法。
    4 子类继承抽象类必须实现其中抽象方法,除非子类为抽象类。 
       private void print(){};此语句表示方法的空实现。 
       abstract void print(); 此语句表示方法的抽象,无实现。
# 接口和抽象类的区别
    1 接口只能包含抽象方法(jdk9以后可被实现),抽象类可以包含普通方法。 
    2 接口只能定义静态常量属性,抽象类既可以定义普通属性,也可以定义静态常量属性。 
    3 接口不包含构造方法,抽象类里可以包含构造方法。     
      抽象类不能被实例化,但不代表它不可以有构造函数,抽象类可以有构造函数,备继承类扩充

5、java面向对象三大特性:封装继承多态

# 封装 : 将对象的属性和实现细节隐藏起来,只提供公共的访问方式。
	好处:
		a、将外界的变化隔离开,使程序具备独立,安全和稳定性。
 		b、便于设计者使用,提高了代码的复用性
# 继承:继承是从已有的类派生出新的类,新的类能继承已有类的数据属性和行为,并扩展新的功能。
 	作用:
 		a、父类具备的方法子类可直接继承过来,不用重新书写,提高了代码的复用性
        b、让类与类之间产生了关系,有了关系才有了多态的实现。
	   c、java支持单继承,译为多继承存在安全隐患(当多个父类存在相同功能时,子类不确定要运行那个),java支持多层继承,即父类			还可以继承其他的类。java用另外一种机制解决了单继承的问题,即多实现。
# 多态:允许不同类型的子对象对统一消息做出不同的响应。
 	java中多态的表现形式:
 		a、父类引用指向子类对象
		b、父类引用自己的子类对象

6、重写和重载

# 重写Override:子类继承父类的非私有方法,并且重新定义
	1、重写是在【运行期】间的活动,通过调用者的实际类型来确定调用的方法版本。
	2、重写是父类与子类之间多态性的表现。父类的构造方法不能被重写
	3、重写只发生在可见的实例方法中:
   	     ​ 静态方法不存在重写,形式上的重写只能说是隐藏。
         ​ 私有方法也不存在重写,父类中private的方法,子类中就算定义了,就是相当于一个新的方法。
         ​ 静态方法和实例方法不存在相互重写。
    4、重写满足一个规则:两同两小一大
         ​ 两同:方法名和形参列表一致(和重载形式上最大的不同)
         ​ 两小:重写方法的返回值(引用类型)和抛出异常,要和被重写方法的返回值(引用类型)和抛出异常相同或者是其子类。注意,		 	一旦返回值是基本数据类型,那么重写方法和被重写方法必须相同,且不存在自动拆装箱的问题。
         ​ 一大:重写方法的访问修饰符大于等于被重写方法的访问修饰符(这句话同时说明了父类的私有方法不能被重写,因为private的访			问权限最小。只能被自己的类访问,作为外部类的子类如果重新定义,那也只是定义了一个新的方法,而不是重写)
          
 # 重载:方法名相同,参数不同(类型、个数、顺序不同)。
     1、重载是在编译器间的活动
     2、重载方法的返回值类型、访问修饰符、抛出的异常可以不同
     3、	重载是一个类中多态的体现
     
  # 总结
  	重写和重载都是java多态的体现。区别在于前者是运行时的多态性,后者时编译时的多态性
  	重写两同(方法名和参数)、两小(返回值和抛出的异常是同类或者子类)、一大(访问权限【大于等于】父类的访问权限)
  	重载记牢定义:方法名相同、参数不同(类型、个数、顺序)

7、访问修饰符

在这里插入图片描述

三、IO流

1、IO流导图

img

2、字节流FileInputStream和FileOutputStream

FileInputStream

public static void main(String[] args) {
   
        /**
         * 一、操作io流的步骤
         * 1、选择源
         * 2、选择流
         * 3、操作流
         * 4、关闭流
         * 二、FileInputStream
         * in.read()返回值为读取字节的ascli码,即字节本身
         * in.read(bytes)返回值为读取的字节长度
         * available可以获取未读的字节数
         */
        FileInputStream in = null;
        try {
   
            in = new FileInputStream("D:/javaSe复习/基础/src/a.txt");
            byte[] bytes = new byte[1024];
            int readcount = 0;
            System.out.println("总字节数:"+in.available());//available获取未读的字节数,可以用来获取文件的字节大小
            while ((readcount = in.read(bytes)) != -1){
   
                String str = new String(bytes,0,readcount);
                System.out.println(str);
            }
        } catch (FileNotFoundException e) {
   
            e.printStackTrace();
        } catch (IOException e) {
   
            e.printStackTrace();
        } finally {
   
            if (in == null) {
   
                try {
   
                    in.close();
                } catch (IOException e) {
   
                    e.printStackTrace();
                }
            }
        }
    }

FIleOutputStream

 public static void main(String[] args) {
   
        OutputStream out = null;//创建流
        try {
   
            out = new FileOutputStream(new File("b.txt"));//选择源
            out.write("hello word".getBytes());//操作流
            out.flush();//刷新缓冲区
        } catch (FileNotFoundException e) {
   
            e.printStackTrace();
        } catch (IOException e) {
   
            e.printStackTrace();
        } finally {
   
            if (out == null) {
   
                try {
   
                    out.close();//关闭流
                } catch (IOException e) {
   
                    e.printStackTrace();
                }
            }
        }
    }

文件复制

  public static void main(String[] args) {
   
        InputStream in = null;
        OutputStream out = null;
        try {
   
            in = new FileInputStream("b.txt");//选择要复制的文件
            out = new FileOutputStream("copy.txt");//复制后的文件名
            byte[] bytes = new byte[1024];
            int readcount = 0;
            while ((readcount = in.read(bytes)) != -1){
   
                out.write(bytes,0,readcount);//写入到文件中
            }
            out.flush();
        } catch (FileNotFoundException e) {
   
            e.printStackTrace();
        } catch (IOException e) {
   
            e.printStackTrace();
        } finally {
   
            if (in == null) {
   
                try {
   
                    in.close();
                } catch (IOException e) {
   
                    e.printStackTrace();
                }
            }
            if (out == null) {
   
                try {
   
                    out.close();
                } catch (IOException e) {
   
                    e.printStackTrace();
                }
            }
        }
    }

3、IO流分类

字节流: FileInputStream、 FileOutPutStram(重点)

字符流: FileReader、 FileWriter

缓冲流: BufferedInputStram、 BufferedOutputStram、 BufferedReader、 BufferedWriter

转换流: InputStramReader 、 OutPutStreamWriter

标准流: PrintStream、 PrintWriter

数据流: DataInputStream、 DataOutputStream

对象流:ObjectInputStream、 ObjectoutputtStream(重点)

四、多线程

1、相关概念


程序:是为完成特定任务,用某种语言编写的一组指令的集合,即指一段静态的代码,静态对象。
进程:是程序的一次执行过程,或是正在运行的一个程序,是一个动态的过程,有它自身的产生,存在和消亡的过程。-------生命周期
线程:进程可进一步细化为线程,是一个程序内部的一条执行路径

# 线程与进程之间的关系与特点
	进程与进程之间相互独立。线程是进程的最小执行单位,一个进程程可以有多个线程
	线程之间的对内存和方法区共享,但是栈内存独立,一个线程一个栈
	线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。

串行:一个线程执行到底,相当于单线程。

并发:多个线程交替执行,抢占cpu的时间片,但是速度很快,在宏观角度看来就像是多个线程同时执行。

并行:多个线程在不同的cpu中同时执行。

# 并发与并行的区别:
    并发严格的说【不是同时】执行多个线程,只是线程交替执行且速度很快,相当于同时执行。
    而并行是同时执行多个线程,也就是多个cpu核心同时执行多个线程。

线程分类:

1、守护线程(如垃圾回收线程,异常处理线程)
2、用户线程(如主线程)
若JVM中都是守护线程,当前JVM将退出。

2、java多线程的实现方式


方法一、继承于java.lang.Thread类(不推荐)

步骤:

  1. 继承Thread类
  2. 重写run方法
  3. 创建线程对象
  4. 线程对象调用start()方法,开启一个栈
public class TestThread {
   
    public static void main(String[] args) {
   
        test test = new test();
        test.start();//开启分支线程,开启一个栈空间
        for (int i = 0; i < 1000; i++) {
   
            System.out.println("主线程"+i
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值