文章目录

  • 类的四种加载
  • OOP
  • 原理:动态绑定
  • 数据类型
  • 抽象类
  • 从final讲继承
  • JSP与Servet,视图与控制
  • static静态
  • == 与 equals的区别
  • public等作用域
  • 接口与抽象的区别
  • final,finally,finalize
  • String,StringBuilder,StringBuffer
  • OBject类方法
  • length属性与length方法
  • hashCode() collections常用
  • 线程
  • 反射
  • 流操作
  • 多线程
  • 线程安全
  • 创建线程
  • 为什么要实现Serializable接口
  • 内部类


类的四种加载

Object obj = new Object();

引用变量信息保存在 虚拟栈

对象实例数据保存在 堆区(GC新生代区),
对象类型数据(接口,方法,版本,静态成员等)保存在 方法区

指向对象实例数据的指针在 句柄池
指向对象类型数据的指针在 句柄池
句柄池在堆区

类加载器会先加载方法区,即将静态成员装载到方法区内,变相创建对象,并且方法区只能被装载一次.


程序计数器:当前线程执行到的代码行
本地方法栈:运行C之类的native方法

## 内部类助外部类实现多继承

内部类可以继承一个与外部类无关的类,并在外部类中,供外部类使用内部类对象的相关方法,变相实现多继承

如儿子同时继承父母亲的特特色(功能)

interface Father{ public int strong();}
interface Mother{ public int kindHeart();}

class FatherImpl extends

OOP

抽象,继承,封装,多态

抽象
就是把现实世界中的某一类东西按一定的边界提取出来.系统需要什么就抽象什么,多余的统统不考虑

数据属性抽象,过程行为抽象
封装
封装使得软件能模块化开发,特点是高内聚,低耦合,设计模式.
最典型的封装就是对象,将对象内的属性私有化,只供对象内部方法调用,对外公开方法,供人调用.注意要把对同一类事物的操作与相关属性数据放到同一个类中.
继承
在一个已经存在的类的基础上,加入若干新内容,或修改原来的方法使之更适合特殊需要.
特点,子类之间可以自动共享父类的数据和方法.该机制提高了软件的可重用型和可拓展性
多态
客户端源码中有这样一句
Father son1 = new Son1();//Son1继承父类show1方法,自定义show2方法
编译器器不会制定son1这个引用到底指向哪个类型

运行
son1.show1();
运行方法时才确定son1这个引用对象调用的是Son1类里继承的父类方法

原理:动态绑定

  • 编译时看的是引用的声明,像Father1 father1 = new Son1();编译器只会知道father1的声明类型是Father1,找方法也在Father1中找.
  • 所以Father1中有show1方法,故father1.show1()调用成功,但是Father1中没有show2方法,故father1.show2()编译出错。
  • 至于father1.show1()最终调用的是子类的show1方法,则就是动态绑定的问题。
  • 动态绑定:运行时自动确定调用哪个方法的现象。
    动态绑定调用的全过程:
  • 编译器查看对象的创建类型和调用的方法名,然后一一列举出声明类型和该类型的超类中同方法名的所有方法(超类中的需要是public属性的);
  • 根据调用方法的参数,选择合适的一个函数(合适指的是类型完全相同或者自动转换类型后符合)。如果没找到那么直接报错。
  • 虚拟机确定对象的实际类型,寻找该类型下的合适方法调用,如果没找到则到超类中去找。
    -静态绑定(如果方法为private,final,static则采用静态绑定,编译时已经索引好具体调用的地址)

数据类型

8+1+1 八种基本+枚举+引用

抽象类

非抽象类继承一个抽象类,必须覆盖父类所有抽象方法
abstract 不可private、static、final、native

从final讲继承

继承类意味着子类会有改动,不然继承个屁
继承时继承方法却不意味会改动它,因为改动它叫覆盖
  • 就近原则 final 修饰的变量不可变引用,引用对象还是可变的
  • 所以final类不可修改,不可继承
  • 普通类中final方法可以继承,不可覆盖
  • final 不可修饰abstract
  • final可以重载,因为重载不与它冲突(重载并没有说谁在谁的基础上改动生成新方法).它欢迎被人使用,但不可修改

JSP与Servet,视图与控制

  • Servlet 完全是 JAVA程序代码构成,擅长于流程控制和事务处理,通过Servlet 来生成动态网 页很不直观.
  • JSP 由 HTML 代码和 JSP 标签构成的.jsp文件,可以方便地编写动态网页.
  • 因此在实际应用中采用 Servlet 来控制业务流程,而采用 JSP(简易Servet) 来生成动态网页.
  • JSP嵌入JAVA代码,Servet嵌入HTML代码

static静态

静态成员属于类,只要程序加载了类的字节码,静态成员就会被分配空间,可以直接调用
  • 静态代码块内部不可访问非静态成员,因为类加载时,无法确定非静态成员的内容(尚未实例化)
  • 非static成员当然可以访问static成员

== 与 equals的区别

  • == 判断基本数据类型的话,用于判断内容或大小是否相等
  • == 判断引用对象时,判断内存地址是否相同
  • 即==用于判断二者是否同一个对象
  • equals相对不会这么严格,只要内容相等就返回True
  • 顺便一提Integer是引用,默认为null

public等作用域

  • public 不管是不是同一个包内都可以访问到
  • protected 同一包内可以访问,不在同一个包内的,必须继承后再共享里面的数据与属性,这是一种对父类的保护,保证每个子类继承的父类数据是一样的.
  • default 同一个包内的类,接口可以互相访问
  • private 仅同一类内可以访问

接口与抽象的区别

  • interface 内成员必须是public,抽象类可以有private
  • interface内不可有普通方法,抽象类可以有
  • 二者都不能new,不是普通类.二者常用语设计模式和代码重构

final,finally,finalize

  • final是声明式关键字,用它声明的成员有以下效果.final属性不可修改(常量),final方法可继承不可覆盖,final类不可继承
  • 局部内部类要访问局部变量,局部变量必须定义成final类,引用始终指向该变量.内部类可访问外部类成员
  • finally 异常语句,表示无论catch了什么,最终都要执行
  • finalize,Object类的垃圾回收方法GC时会用到

String,StringBuilder,StringBuffer

  • String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
  • String str;是字符串常量,属于不可变对象. str只能赋值一次,第二次赋值原理的对象str会被GC回收,JVM新建一个str.于是大量操作的时候,不断回收与创建会使程序运行缓慢,效率低下.
  • StringBuilder与StringBuffer都是字符串变量,属于可变对象.
  • StringBuilder线程不安全,StringBuffer线程安全.
    StringBuilder stringBuilder=new StringBuilder().append(“abc”);
    stringBuilder = stringBuilder.append(“de”);

OBject类方法

  • clone方法
  • getClass方法 ,获取运行时的类型
  • toString方法 打印对象名,对于调用该对象的toString方法
  • finalize 释放资源,很少使用
  • equals方法,在Object的源码中equals返回的是
    public boolean equals(Object obj){
    this == obj;
    }

length属性与length方法

  • Array.length,String.length()

hashCode() collections常用

  • Set集合不允许有重复元素.
  • 看某个对象是否已经在一个对象集合内,先用hashCode()快速对比,再在hashCode()为True的对象里,用equals找内容相等的对象,若都找不到,则说明该集合内,并没有与该对象重复的对象.

线程

线程构造器必须传入一个实现了Runnable接口的类的对象,以此创建类线程对象
public Study implements Runable(){}
Thread thread = new Thread(new Study())

  • 等待获取锁 : wait(long timeout)
  • notify,notifyAll,interrupt,wait时间到

反射

我们可以通过反射动态读取正在运行的类的元数据
  • 优点灵活,可拓展,实现正在运行的类可配置
  • 缺点是解释操作,字段接入的速度非常慢.
  • 用处:jdbc,java框架,jdk动态代理

流操作

  • 字节流继承于:InputStream,OutputStream
  • 字符流继承于:InputStreamReader,OutputStreamWriter
  • 当然在java.io包里还有更多其他流操作,需要的时候查一下JDK文档即可

多线程

本质,在同一个进程中,有多个不同的执行路径
  • 充分利用系统资源,缩短程序响应时间
  • 进程是线程的集合
  • 线程同步,线程都在同一个路径内,前一个线程执行完毕后,下一个线程再接着执行
  • 线程异步,进程中有多个不同的执行路径
  • 线程间强行同步,synchronized,wait,notify

线程安全

  • 同步是线程安全的
  • 假设种树这个任务有三个线程:挖坑线程,种树线程和填坑线程,后面的线程(上锁)必须等前一个线程完成才能进行,而不是按时间顺序来进行.
  • 否则按时间执行的话,就会出现一旦某个线程出问题未响应,时间自动执行下一个线程,极大概率出现数据不存在,对象不存在,或内存泄漏的问题
  • 根据同步实现线程安全:synchronized,wait都是所后面的线程,前一个线程完成后才会执行后一个线程
  • 根据不可修改实现线程安全:final,Lock

创建线程

  • 继承Thread类,自己实现run方法, new 一个对象后,调用对象的start方法
  • 写一个目标类实现Runable接口,实现run方法,new一个目标类对象后,将该对象传入Thread类的构造方法中,启用Thread对象的start方法
  • 推荐实现Runable接口,因为这样可以再继承别的类,而继承Thread类只能是单继承.我们都知道,Java是只允许单继承的,我们一定要继承Thread类的话,可以用内部类,间接实现多继承

为什么要实现Serializable接口

一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才能被序列化

内部类

类中类实现多继承
  • 内部类的构造方法挪到外部类,就是外部类的普通方法
class A{    
    void output(){}
    class B{
        void output(){}
    }
    B newB(){
        B b = new B();
        return b
    }
    
    void main(){
        
    }
}