Please enable Javascript to view the contents

Java基础

 ·  ☕ 9 分钟  ·  🎅 qqnv
    🏷️

基础类型

计算机的存储单元

计算机存储设备的最小单元叫位(bit),通常用b表示
计算机最小的存储单元叫字节(byte)B表示,由连续的8个位组成
1B(字节)= 8bit 1kb = 1024B

数据类型

  • 基本数据类型
    • 数值型
      • 整数(byte, short, int, long)
      • 浮点数(float, double)
      • 字符(char)
    • 非数值型
      • 布尔(boolean)
  • 引用数据类型
    • 类(class)
    • 接口(interface)
    • 数组([])
数据类型 关键字 内存占用 取值范围
整数 byte 1 -128~127
short 2 -32768~32767
int 4 -2的31次方~2的31次方-1
long 8 -2的63次方~2的63次方-1
浮点数 float 4 负数-3.402823E+38~-1.401298E-45
正数1.401298E-45~3.402823E+38
double 8 负数-1.797693E+308~-4.9000000E-324
正数4.9000000E-324~1.797693E+308
字符 char 2 0~65535
布尔 boolean 1 true、false

说明:E+38表示乘以10的38次方,E-45表示乘以10的负45次方

Java内存模型

当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在。不存在创建新的,存在则复用

基本数据类型比较的事数据值 引用数据类型比较的是地址值

Java关键字static理解

被static修饰的成员变量叫静态变量
特点:被该类所有对象共享,不属于对象,属于类,随着类的加载而加载,优先于对象存在可被类名和对象名调用,存放在堆内存静态区中

被static修饰的成员方法叫静态方法
特点:多用在测试类和工具类中,JavaBean类中很少使用

工具类私有化构造方法,目的是不让外界创建它的对象,里面的方法定义为静态方便调用

静态内部类和非静态内部类区别:是否持有外部类的状态,静态内部类持有外部类的实例

  • 静态方法只能访问静态变量和静态方法
  • 非静态方法可以访问静态变量或静态方法,也可以访问非静态成员变量和非静态成员方法
  • 静态方法中没有this关键字

Java关键字final理解

  • final修饰类,该类不能被继承,且该类中所有方法都被隐式指定为final方法
  • final修饰的方法不能被重写
    一个类的private方法被隐式指定为final方法
  • final修饰成员变量,必须要赋初始值,且只能初始化一次
    • 如果修饰的是基本类型,则变量值不能改变
    • 如果修饰的是引用类型,则引用的地址值不能更改,但这个引用所指的对象的内容可以改变

抽象类和接口

抽象类

抽象类的设计目的,是代码复用。当不同的类具有相同的行为(记为行为集合A),且其中一部分行为的实现方式一样时(A的非真子集,记为B),可以让这些类都派生于一个抽象类。在这个抽象类中实现了B,避免让所有的子类都实现B,这就达到了代码复用的目的。而A减B的部分,留给各个子类自己实现,正是因为A-B在这里没有实现,所以抽象类不允许实例化出来(否则当调用A-B时,无法执行)。

  • 实现了一部分协议的半成品
  • 可以有状态,可以有方法实现
  • 必须由子类继承后使用

接口

接口设计的目的,是对类行为的约束(更准确的说是一种“有”约束,因为接口不能规定类不可以有什么行为),也就是提供一种机制,可以强制不同的类有相同的行为。它只约束了行为的有无,但不对如何实现行为进行限制。

  • 直观理解就是一种约定
  • 不能有状态
  • 必须由类进行实现后使用

共性

  • 比较抽象,不能直接实例化
  • 有需要子类(实现类)实现的方法
  • 父类(接口)变量可以接收子类(实现类)的实例赋值

区别

抽象类是对类本质的抽象,表达的是is a的关系,比如:BMW is a Car,抽象类包含并实现子类的通用特性,将子类存在差异化的特性进行抽象,交由子类去实现。

接口是对行为的抽象,表达的是like a的关系,比如:Bird like a Aircraft(像飞行器一样可以飞),但其本质上is a Bird。接口的核心是定义行为,即实现类可以做什么,至于实现类主体是谁、是如何实现的,接口并不关心。

使用场景:当你关注一个事物本质的时候,用抽象类;当你关注一个操作的时候,用接口。

抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的所有共性,虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口,在设计阶段会降低难度。

  • 抽象类有状态,接口不能有状态
  • 抽象类有方法实现,接口只能有无状态的默认实现
    抽象类可以有普通成员函数,接口中只能存在public abstract方法
    抽象类中的成员变量可以是各种类型的,接口中成员变量只能是public static final类型的
  • 抽象类只能单继承,接口可以多实现
  • 抽象类反应本质,接口体现能力

接口中成员的特点

  • 成员变量 只能是常量,默认修饰符public static final
  • 构造方法没有
  • 成员方法 只能是抽象方法,默认修饰符public abstract
  • jdk7以前,接口中只能定义抽象方法
  • jdk8新特性,接口中可以定义有方法体的方法(默认方法(修饰符default)或静态方法(修饰符static))
  • jdk9新特性,接口中可以定义私有方法(可以是静态(给静态方法服务)或非静态(给默认方法服务))
  • 接口中如果没有成员,那么它就是个标记性接口
  1. 接口代表规则,是行为的抽象,想要让哪个累拥有某个行为,让这个类实现对应接口就行
  2. 当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态

适配器模式

当一个接口中抽象方法过多,但是我们只要使用其中一部分的时候,可以用适配器实现
编写中间类adapter,实现对应接口,对接口中的抽象方法进行空实现,让真正的实现类继承中间类,并重写需要用的方法,为了避免其他类去创建适配器类的对象,适配器用abstract修饰

内部类

成员内部类

  • 写在成员位置,在成员内部类里,jdk16以前不能定义静态变量,16开始才可以定义
  • 两种创建方式,一种是内部提供对象的方法(当内部类用pravite修饰时)
    另一种是Outer.Inner oi = new Outer().new Inner();

静态内部类

  • 用static修饰符修饰的内部类
  • 直接创建即可Outer.Inner oi = new Outer.Inner();
  • 若调用静态方法则直接Outer.Inner.show();
    若调用非静态方法则要先创建对象,再调用

局部内部类

  • 定义在方法中
  • 外界无法直接使用,需在方法内部创建对象并调用
  • 该类可以直接访问外部类的成员和方法内的局部变量

匿名内部类

  • 隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置
  • 格式是new 类名或接口名(){重写方法;};
  • 包含了继承或实现,方法重写,创建对象,整体是一个类的子类对象或接口的实现类对象
  • 使用场景:当方法的参数是接口或者类时,以接口为例,可以传递这个接口的实现类对象,如果实现类只要使用一次,就可以用匿名内部类简化代码

equels

String中的equals方法先判断参数是否为字符串,如果是则判断内部属性,如果不是直接返回false
Object中的equals方法默认使用==比较两个对象的地址值
若想比较两个对象的属性值,则需要重写Object中的equals方法

Object

object中的克隆默认是浅克隆,深克隆可以利用gson库实现

Gson gson = new Gson();
//把对象变成一个字符串
String s = gson.toJson(u1);
//再把字符串变回对象
User user = gson.fromJson(s,User.class);
  1. 需重写object中的clone()
  2. 让JavaBean类实现Cloneable接口
  3. 创建原对象并调用clone()

浅克隆:基本数据类型直接拷贝,引用数据类型拷贝地址值
深克隆:基本数据类型直接拷贝,字符串复用串池数据,其他引用数据类型会重新创建对象,并拷贝里面的数据,将新内存地址赋值给新对象

BigInteger

  • 如果BigInteger表示的数字没有超出long的范围,可以用静态方法获取
  • 如果BigInteger表示的数字超出long的范围,可以用构造方法获取
  • 对象一旦创建,BigInteger内部记录的值不能发生改变
  • 只要进行计算都会产生一个新的BigInteger对象

BigInteger表示一个大整数常见方法有:
加:add 减:subtract 乘:multiply 除:divide、divideAndRemainder
比较:equals、max、min
次幂:pow
转成整数:intValue、longValue等

BigDecima

  • 用于小数的精确计算
  • 用于表示很大的小数
  • 如果BigInteger表示的数字没有超出Double的范围,可以用.valueof()
  • 如果BigInteger表示的数字超出Double 的范围,可以new出来

正则表达式(Pattern)

作用

  • 校验字符串是否满足规则
  • 在一段文本中查找满足要求的内容

Matcher:文本匹配器

正则表达式在字符串方法中的使用

方法名 说明
public String[] matches(String regex) 判断字符串是否满足正则表达式规则
public String replaceAll(String regex, String newStr) 按照正则表达式规则进行替换
public String[] split(String regex) 按照正则表达式规则切割字符串

时间类

JDK8以前

Date

  • new Date()获取当前时间
  • new Date(0L)获取时间原点 (1970年1月1日8:00)

SimpleDateFormat

  • format("")将时间转化为给定格式的时间字符串
  • parse("")解析字符串的文本转换为时间对象

Calendar

可以单独获取修改时间中的年月日,该类是个抽象类,不能直接创建对象

该类获取的月份要+1

方法名 说明
public static Calendar getInstance() 根据系统不同的时区来获取不同的日历对象
public final Date getTime() 获取日期对象
public final Date setTime(Date date) 给日历设置日期对象
public long getTimeInMillis() 拿到时间毫秒值
public void setTimeInMillis(long mills) 给日历设置时间毫秒值
public int get(int field) 取日历中某个字段信息
public void set(int field,int value) 修改日历的某个字段信息
public void add(int field,int amount) 为某个字段增加/减少指定的值

ZoneId时区

方法名 说明
static Set getAvailableZoneIds() 获取Java中支持的所有时区
static ZoneId systemDefault() 获取系统默认时区
static ZoneId of(String zoneId) 获取一个指定时区

JDK8及以后

Date类

ZoneId:时区

Instant:时间戳

ZoneDateTime:带时区的时间

日期格式化类

DateTimeFormatter:用于时间的格式化和解析

日历类

LocalDate:年月日

LocalTime:时分秒

LocalDateTime:年月日时分秒

工具类

Duration:时间间隔(时分秒纳秒)

Period:时间间隔(年月日)

ChronoUnit:时间间隔(所有单位)

包装类

在jdk5以前的两种创建包装类对象:

  1. Integer i = new Integer(1); 每次创建都会创建一个新的对象
  2. Integer i = Integer.valueOf(1);-128~127之间会复用对象,底层会把对象都创建好放在一个长为256的数组里以便复用

jdk5以后会自动拆箱、自动装箱

Integer

方法名 说明
public static String toBinaryString(int i) 得到二进制
public static String toOctalString(int i) 得到八进制
public static String toHexString(int i) 得到十六进制
public static int parseInt(String s) 将字符串类型的整数转成int类型的整数
分享

qqnv
作者
qqnv
Android Developer