0%

Java

[TOC]

面向对象

概念

面向对象(Object Oriented),对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念。换句话说,对象是真是存在内存的,实例化的类,比如你想要的粥,类就是锅里的粥,实例化就是盛出来放进碗中,而对象就是一碗粥,真实存在,可以被你操控,又或者你女朋友A是你择偶标准(类)实例化出来的对象,真实存在,但择偶标准并不真实存在

对象VS过程

面向过程编程更加注重一个类解决一个问题,是一个解决方案,而不需要你去考虑这个对象具体怎么实现的

换句话说,面向过程就是生产一辆汽车,面向对象就是直接买一辆汽车开,你可以把汽车销售商理解为一个对象的提供商,为你提供服务。

三大核心

三大核心都是尽最大的可能复用代码

继承

定义类的基石(共同的属性和方法)

避免子类重复定义,单继承(只能继承一次)

子类拥有父类的所有属性和方法(除了private修饰的属性不能拥有)

目的:代码复用

重载:同名函数不同参数

重写:重写方法实现方式(子类个性化)

final的几个问题:

  • final修饰的类不允许继承
  • final修饰的方法不允许重写
  • final 修饰属性,则该类的该属性不会进行隐式的初始化,所以 该final 属性的初始化属性必须有值,或在构造方法中赋值(但只能选其一,且必须选其一,因为没有默认值!),且初始化之后就不能改了,只能赋值一次
  • final 修饰变量,则该变量的值只能赋一次值,在声明变量的时候才能赋值,即变为常量

super的几个问题:

  • 访问父类对象,如:super.age,super.eat()
  • 子类构造的过程调用父类的构造方法,默认调用无参构造方法

封装(set/get)

封装(Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须通过严格的接口控制。

封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。

适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

多态

多态就是同一个接口,使用不同的实例而执行不同操作

多态性是对象多种表现形式的体现。

现实中,比如我们按下 F1 键这个动作:

  • 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
  • 如果当前在 Word 下弹出的就是 Word 帮助;
  • 在 Windows 下弹出的就是 Windows 帮助和支持。

基本数据类型

内置数据类型

  • byte(-128~127即2^7,默认0)
  • short(16位,默认0)
  • int(32位,默认0)
  • long(64位,默认0L)
  • float(32位,默认0.0f)
  • double(64位,默认0.0d)
  • boolean(1位默认false)
  • char(16位0~65535)

引用数据类型

引用为指针的另一种变种,引用类型指向一个对象,数组

常量

final修饰

拆箱和装箱

why

数字字符日期等基本类型封装成对象方便处理,但是对于CPU来说,一个完整的对象需要很多的指令,对于内存来说,有需要很多的内存,性能自然很低,所以设计装箱和拆箱,是的基本类型在编程中当做非对象处理,在另外场合有当做对象处理

int的自动拆箱和装箱只在-128到127范围中进行,超过该范围的两个integer的 == 判断是会返回false的。

变量存储方式

基本类型->栈内存

引用类型->堆内存

String和包装类

string基础

字符串属于对象,char属于基本类型,String greetings=“hello,world”

如果如果需要对字符串做很多修改,那么应该选择使用 StringBuffer & StringBuilder 类。通过append可以直接修改,Stringbuilder不是线程安全的但是又速度优势,建议使用,StringBuffer是线程安全

  • appen追加
  • reverse反转
  • delete移除
  • insert将int插入
  • replace替换等

String是final class不可变不可继承,由于不可变,所以拼接字符串会有很多中间无用的对象,所以会影响性能,但不影响正常小批量的字符串拼接

StringBuffer是解决上述问题的方案,提供append和 add方法,拼接至尾部,他的本质是一个县城安全的可修改的字符序列,添加了synchronized,但也付出了性能代价

很多情况下字符串拼接无需线程安全,则可以使用StringBuilder

StringBuffer 和 StringBuilder 二者都继承了 AbstractStringBuilder ,底层都是利用可修改的char数组(JDK 9 以后是 byte数组)。

string基本用法

  • String s1 = “mpptest”
  • String s2 = new String();
  • String s3 = new String(“mpptest”)
  • “==”判断引用内容,equals判断引用地址

string类源码

1
2
3
4
5
6
7
8
9
10
11
public void intern () {
//2:string的intern使用
//s1是基本类型,比较值。s2是string实例,比较实例地址
//字符串类型用equals方法比较时只会比较值
String s1 = "a";
String s2 = new String("a");
//调用intern时,如果s2中的字符不在常量池,则加入常量池并返回常量的引用
String s3 = s2.intern();
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//true
}

(此处待补充)

String和JVM

  • Java栈(线程私有)

    每个Java虚拟机线程都有自己的Java虚拟机栈,Java虚拟机栈用来存放栈帧,每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程

  • Java堆(线程共享)存放所有对象

  • 方法区(线程共享)

    方法区在虚拟机启动的时候被创建,它存储了每一个类的结构信息,例如运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容、还包括在类、实例、接口初始化时用到的特殊方法。在JDK8之前永久代是方法区的一种实现,而JDK8元空间替代了永久代,永久代被移除,也可以理解为元空间是方法区的一种实现。

  • 常量池(线程共享)

    常量池常被分为两大类:静态常量池和运行时常量池。

    静态常量池也就是Class文件中的常量池,存在于Class文件中。
    
    运行时常量池(Runtime Constant Pool)是方法区的一部分,存放一些运行时常量数据。
    

String为什么不可变

变量在栈中,数据本身在堆中,引用不可变

String常用工具

apache-commons

final关键字

Java类和包

抽象类和接口

代码块和代码执行顺序

自动拆箱装箱

Class类和Object类

异常

回调

反射

泛型

枚举类

注解

IO流

多线程

内部类

javac和javap

java8新特性

类和包

序列化和反序列化

继承封装多态实现原理