【Java基础】Java中你必须知道的知识点
本篇博客主要记录Java中面向对象的概念知识和一些基础Java类的使用。属于自己平时学习过程中知识点的“拼凑”,方便自己回顾总结。
1. 什么是面向对象
面向对象是一种优秀的软件设计思想,是相对于面向过程、面向切面等设计思想的一种软件设计理念。它的核心思想是运用更加贴近人类思维的方式去设计软件,将软件中的各个组件抽象成相应的类,再将这些类组装成我们所需的软件系统。这里举个例子,假如用面向对象的方式设计一个电脑,我们会设计CPU类、硬盘类、显示器类、内存类等等,然后将这些类组合在一起设计成Computer类。
面向过程的思想在解决问题时会将问题分解成一个个小的函数,然后按照某种顺序去执行这些方法,当这些方法执行完毕,问题也就解决了。
2. 三大基本特征和五项基本原则
面向对象的三个基本特征是:封装、继承和多态。正是基于这些特征,面向对象的开发语言才能拥有更好的可重用性、扩展性和维护性。
- 封装:将对象的实现细节隐藏起来,然后通过一些公共的方法向外部提供该对象的功能;
- 继承:继承是软件复用的一种重要手段,子类继承父类之后将直接获得父类的属性和方法;
- 多态:对象可以赋给父类对象和接口,但是运行时依然表现出子类或实现类的特征。
面向对象的五大原则如下:
- 单一职责原则(SRP):一个类专注于实现一个功能;
- 开闭原则(OCP):对象或实体应该对扩展开放,对修改封闭;
- 里氏替换原则(LSP):子类可以替换父类并且出现在父类能够出现的任何地方,这就需要我们面向接口编程;
- 依赖倒置原则(DIP):高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象;抽象不应该依赖于具体实现,具体实现应该依赖于抽象;
- 接口隔离原则(ISP):使用多个专门的接口比使用单个接口要好的多。在实际编程中,为了减少接口的定义,将许多方法都放在一个接口中,最后发现,维护和实现接口的时候会花费很多精力。而接口所定义的操作相当于对客户端的一种承诺,这种承诺当然是越少越好,越精练越好,过多的承诺带来的就是你的大量精力和时间去维护。
3. Java的平台无关性
Java语言能跨平台的关键是JVM能跨平台。JVM还支持的语言有Kotlin、Groovy、JRuby、Jython、Scala等。
4. 值传递和引用传递
基本数据类型,保存的是数据本身的值,按值传递;引用类型的变量保存的是对象在内存中的地址,按引用传递(引用传递可以看成是一种特殊的值传递)。
5. 方法重载和重写
方法重载是指在同一个类中存在多个方法名相同,但是方法参数不用的方法;
方法重写是指子类继承父类后,重新修改了父类的某个方法的行为(子类中存在这样一个方法,这个方法的方法名方法参数都和父类中某个方法一样,但是这个两个方法的方法体不一样,这种情况我们称子类方法重写了父类方法)
6. 基本数据类型
Java中有8种基本数字类型。从大类上分的话分别是布尔型,字符型,整形和浮点型。对应bool,byte,char,short,int,long,float和double类型。
- byte:一个字节,8个bit位,-2^7 ~ 2^7-1
- char : 2个字节,16个bit位,0 ~ 2^16-1 ;
- short:2个字节,16个bit位,-2^15 ~ 2^15-1
- int:4个字节,32个bit位,-2^31 ~ 2^31-1
- long:8个字节,64个bit位,-2^63 ~ 2^63-1
- float:4个字节,32个bit位
- double:8个字节,64个bit位。
在计算机中,浮点数用来近似表示任意某个实数。浮点数分为双精度浮点数和单精度浮点数。单精度占4个字节,双精度占8个字节,表示的范围更大。在要求精确计算的场合,不建议使用浮点型数据。因为浮点数计算的结果不是很精确,是近似的结果。这种情况应该使用BigDecimal。这边举个BigDecimal使用的简单列子:
BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(1.1));
BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(2.223));
String str1 = bigDecimal1.add(bigDecimal2).toString();
//减法
bigDecimal1 = new BigDecimal(String.valueOf(2.2));
bigDecimal2 = new BigDecimal(String.valueOf(10.1));
String str2 = bigDecimal1.subtract(bigDecimal2).toString();
//乘法
bigDecimal1 = new BigDecimal(String.valueOf(1.1));
bigDecimal2 = new BigDecimal(String.valueOf(2.234));
String str3 = bigDecimal1.multiply(bigDecimal2).toString();
//除法
bigDecimal1 = new BigDecimal(String.valueOf(4.4));
bigDecimal2 = new BigDecimal(String.valueOf(3));
//除法需要设置精度和四舍五入的方式
String str4 = bigDecimal1.divide(bigDecimal2,3, RoundingMode.HALF_UP).toString();
//结果
System.out.println("加法结果:" + Double.valueOf(str1));
System.out.println("减法结果:" + Double.valueOf(str2));
System.out.println("乘法结果:" + Double.valueOf(str3));
System.out.println("除法结果:" + Double.valueOf(str4));
7. 包装类型
包装类型是相对于基本数据类型来讲的。Java中有8种基本数据类型,每个基本数据类型都有相对的包装类型。比如int的包装类型是Integer。包装类型是引用类型,而且都是不可变类。
- 自动装箱:将基本数据类型赋值给包装类型的过程,实现原理是编译器层面new了一个包装类再赋值给相应的变量;
- 自动拆箱:包装类型直接赋值给基本数据类型,实现原理类似,也是编译器层面调用了包装类的getValue方法再赋值给对应的基本数值类型。
比较有趣的是,包装类型在加载的过程中都会缓存某些值的类。比如Integer会缓存-128到127的类。
//不会使用缓存的数据
Integer num1 = new Integer(1);
//会使用缓存的数据
Integer num2 = 1;
通过设置-XX:AutoBoxCacheMax=?这个参数,可以调整Integer缓存的最大值。当然其他包装类型也有类似的行为,Byte、Short和Long都缓存了-128到127的类,Character缓存了0到127的类,但是这些类不能像Integer那样修改缓存的最大值。
8. String类
String是我们开发过程中使用的最多的一个类。它是一个不可变类,不能被继承。String类常用的方法如下图。另外String还有一个format方法可以进行非常丰富的格式化功能。具体的使用方式可以参考这篇博客
8.1 subString方法的原理
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
}
String的类别是用char数组实现的,从代码中可以看到char数组用final修饰了,所以是不可变的。调用String的subString方法其实是又重新new了一个新的String对象:
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}
8.2 repalce函数
- replace(char oldChar, char newChar):使用newChar替换所有的oldChar,不是基于正则表达式的;
- replace(CharSequence target, CharSequence replacement):替换所有,基于正则表达式的;
- public String replaceFirst(String regex, String replacement):替换regex匹配的第一个字符串,基于正则表达式;
- replaceAll(String regex, String replacement):替换regex匹配的所有字符串,基于正则表达式;
8.3 valueOf函数
String提供了很多valueOf函数,比如valueOf(int i)、valueOf(double i)等。其实背后调用的是对应包装类的toSting方法
public static String valueOf(int i) {
return Integer.toString(i);
}
//Integer的toString方法
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true);
}
8.3 常量池(来源于互联网)
常量池可以分为Class常量池、运行时常量池和字符串常量池:
- class文件常量池
在Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用。下面对字面量和符号引用进行说明。
字面量类似与我们平常说的常量,主要包括以下两种
- 文本字符串,例如String a = "aa"。其中"aa"就是字面量。
- 被final修饰的变量。
符号引用包括以下形式:
- 类和接口和全限定名:例如对于String这个类,它的全限定名就是java/lang/String。
- 字段的名称和描述符:所谓字段就是类或者接口中声明的变量,包括类级别变量和实例级的变量。
- 方法的名称和描述符:所谓描述符就相当于方法的参数类型+返回值类型。
运行时常量池
我们知道类加载器会加载对应的Class文件,而上面的class文件中的常量池,会在类加载后进入方法区中的运行时常量池【此时存在在内存中】。并且需要的注意的是,运行时常量池是全局共享的,多个类共用一个运行时常量池。并且class文件中常量池多个相同的字符串在运行时常量池只会存在一份。注意运行时常量池存在于方法区中。字符串常量池
看名字我们就可以知道字符串常量池会用来存放字符串,也就是说常量池中的文本字符串会在类加载时进入字符串常量池。那字符串常量池和运行时常量池是什么关系呢?上面我们说常量池中的字面量会在类加载后进入运行时常量池,其中字面量中有包括文本字符串,显然从这段文字我们可以知道字符串常量池存在于运行时常量池中。也就存在于方法区中。到了JDK1.7时,字符串常量池就被移出了方法区,转移到了堆里了。那么我们可以推断,到了JDK1.7以及之后的版本中,运行时常量池并没有包含字符串常量池,运行时常量池存在于方法区中,而字符串常量池存在于堆中。
程序运行时,除非手动向常量池中添加常量(比如调用intern方法),否则jvm不会自动添加常量到常量池。
8.4 intren方法
intren方法的作用是检测常量池中是否有当前字符串,有的话就返回常量池中的对像,没有的话就将当前对像放入常量池。
8.5 兄弟类之间的比较
公众号推荐
欢迎大家关注我的微信公众号「程序员自由之路」
【Java基础】Java中你必须知道的知识点的更多相关文章
- java基础---->java中正则表达式二
跟正则表达式相关的类有:Pattern.Matcher和String.今天我们就开始Java中正则表达式的学习. Pattern和Matcher的理解 一.正则表达式的使用方法 一般推荐使用的方式如下 ...
- Java基础学习中一些词语和语句的使用
在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看brea ...
- Java基础-Java中的堆内存和离堆内存机制
Java基础-Java中的堆内存和离堆内存机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Java基础-Java中的内存分配与回收机制
Java基础-Java中的内存分配与回收机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一. 二.
- Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock)
Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在学习Java的之前,你可能已经听说过读 ...
- Java基础-Java中的并法库之线程池技术
Java基础-Java中的并法库之线程池技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是线程池技术 二.
- Java基础-Java中23种设计模式之常用的设计模式
Java基础-Java中23种设计模式之常用的设计模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.设计模式分类 设计模式是针对特定场景给出的专家级的解决方案.总的来说设 ...
- Java基础-JAVA中常见的数据结构介绍
Java基础-JAVA中常见的数据结构介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是数据结构 答:数据结构是指数据存储的组织方式.大致上分为线性表.栈(Stack) ...
- Java基础__Java中自定义集合类
Java基础__Java中集合类 传送门 自定义MyArrayList集合实现:增加数据.取数据.查看集合中数据个数方法 package com.Gary; public class MyArrayL ...
- Java基础(中)
面向对象基础 面向对象和面向过程的区别 两者的主要区别在于解决问题的方式不同: 面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题. 面向对象会先抽象出对象,然后用对象执行方法的方式 ...
随机推荐
- where和having区别
壹: where后面不能跟聚合函数(sum.avg.count.max.min) having后面可以跟 贰: where和having都能用: select goods_price,goods_na ...
- 两个实例轻松理解js函数预解析
js函数预解析 例子1: 先上一段代码,看看能不能写出最终的执行结果. console.log(a); var a = 1; console.log(a); function a(){ console ...
- python:json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes问题解决
有如下一个文件,内容如下 { "test1": "/root/test/test1.template", "test2": "/r ...
- 【并发编程】Java并发编程传送门
本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. [并发编程系列博客传送门](https://www.cnblogs.com/54 ...
- C#中提示:当前上下文中不存在名称“ConfigurationManager”
场景 想要在程序中获取App.config中设置的内容. 想要通过 ConfigurationManager.AppSettings[key]; 来进行获取,已经添加 using System.Con ...
- DC8: Vulnhub Walkthrough
镜像下载链接: https://www.vulnhub.com/entry/dc-8,367/#download 主机扫描: http://10.10.202.131/?nid=2%27 http:/ ...
- web 自动化遇到 shadowDOM 节点你会操作吗?
本文转载自: http://www.lemfix.com/topics/971 近期有同学在做web自动化的时候,发现页面上有些元素,在selenium中无法通过xpath来定位,各种原因找了半天,都 ...
- MSP430系列单片机特性及应用领域
概述 MSP430系列单片机是德州仪器1996年开始推向市场的一种16位超低功耗的混合信号处理器,给人们留下的最大的亮点是低功耗而且速度快,汇编语言用起来很灵活,寻址方式很多,指令很少,容易上手.主要 ...
- Prometheus学习系列(六)之Prometheus 查询说明
前言 本文来自Prometheus官网手册和 Prometheus简介 Prothetheus查询 Prometheus提供一个函数式的表达式语言PromQL (Prometheus Query La ...
- vue2y引入iview,在ie11报错的解决办法
在ie11中打开vue项目一片空白,F12打开控制台发现如下错误 只需要在build/webpack.base.conf.js中加一行代码即可