• 你必须知道的Java基础知识


    本篇博客主要记录Java中面向对象的概念和Java语法的基础知识。

    面向对象

    什么是面向对象

    面向对象是一种优秀的软件设计思想,是相对于面向过程、面向切面等设计思想的一种软件设计理念。它的核心思想是运用更加贴近人类思维的方式去设计软件,将软件中的各个组件抽象成相应的类,再将这些类组装成我们所需的软件系统。

    这里举个例子:假如用面向对象的方式设计一个电脑,我们会设计CPU类、硬盘类、显示器类、内存类等等,然后将这些类组合在一起设计成Computer类。

    而面向过程的思想在解决问题时会将问题分解成一个个小的函数,然后按照某种顺序去执行这些方法,当这些方法执行完毕,问题也就解决了。

    三大基本特征和五项基本原则

    面向对象的三大基本特征是:封装、继承和多态。正是基于这些特征,面向对象的开发语言才能拥有更好的可重用性、扩展性和维护性

    • 封装:将对象的实现细节隐藏起来,然后通过一些公共的方法向外部提供该对象的功能;
    • 继承:继承是软件复用的一种重要手段(组合和代理也是代码复用的手段),子类继承父类之后将直接获得父类的属性和方法;
    • 多态:对象可以赋给父类对象或者它实现的接口,但是运行时依然表现出子类或实现类的特征。

    面向对象的五大原则如下:

    • 单一职责原则(SRP):一个类专注于实现一个功能;
    • 开闭原则(OCP):对象或实体应该对扩展开放,对修改封闭;
    • 里氏替换原则(LSP):子类可以替换父类并且出现在父类能够出现的任何地方(这个原则就需要我们面向接口编程);
    • 依赖倒置原则(DIP):高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象,抽象不应该依赖于具体实现,具体实现应该依赖于抽象;
    • 接口隔离原则(ISP):使用多个专门的接口比使用单个接口要好的多:在实际编程中,为了减少接口的定义,将许多方法都放在一个接口中,最后发现,维护和实现接口的时候会花费很多精力,接口所定义的操作相当于对客户端的一种承诺,这种承诺当然是越少越好,越精练越好,过多的承诺带来的就是你的大量精力和时间去维护。不要把不相干的方法放在一个接口中定义。

    另外还有迪米特原则合成服用原则,也需要我们在设计系统和接口时考虑到。

    迪米特法则:又叫最少知识法则,这个法则主张一个类要尽可能少地知道其他类地细节,并且尽可能少地和其他类进行通信交互,只和于自己有密切关系地类进行交互。
    合成服用原则:合成服用原则又称为组合/聚合服用原则(Composite/Aggregate Reuse Principle):尽量采用组合(contains-a)、聚合(has-a)的方式而不是继承(is-a)的关系来达到软件的复用目的。

    合成服用原则最主要地原因是继承会破环封装:基类的很多内部细节都是对派生类可见的,而有些细节可能是不想让子类知道的。关于继承、组合还有聚合的概念可能比较容易搞混,这边也提下。

    继承:子类拥有父类的某些属性和方法,子类可以替换父类;
    组合:是整体与部分的关系,整体离不开部分,部分离开了整体没有意义,如飞机翅膀与飞机的关系;
    聚合:也是整体与部分的关系,但整体可以分离部分,部分也可以离开整体,如火车与车厢的关系,还有就是聚合支付的列子等。

    重载和重写的区别

    重载:是指在一个类里面存在多个方法名相同,但是方法参数不同的方法。

    重写:是指子类在继承父类时,重新改写了父类的某个方法。子类中的这个方法的方法名和方法参数和父类中的完全一样。

    Java基础语法

    Java语言是最流行的编程语言,从刚“出生”,Java语言就号称“一次编译,到处运行”。

    Java语言能跨平台的关键是JVM能跨平台,JVM屏蔽了操作系统的底层差异,让字节码文件在每个平台上都可以执行。

    除了Java,JVM还支持的语言有Kotlin、Groovy、JRuby、Jython、Scala等。另外,随着Oracle对Graal虚拟机的研发,JVM平台将会支持所有的语言,包括JS和C++等语言。

    进行Java开发的第一步是下载一个合适版本的JDK,然后配置JAVA_HOME这个环境变量。但是如果你只是需要运行Java程序,那你只需要安装一个JRE即可。JDK和JRE的关系如下:

    JDK包含:Java编译器、JRE以及常用的Java工具库;
    JRE包含:JVM、类加载器、字节码校验器以及核心类库等。

    然后就是编译执行Java程序

    # -d后面的参数指定生成的字节码文件的生产路径,默认当前目录;
    javac -d destDir HelloWorld.java;
    # 执行Java程序;
    # classpath的作用是提供了一系列路径让Java程序去在这些路径下寻找类,找不到就报错。在Windows上用;号分割,在Linux上用:号分隔
    java -classpath %CLAss_PATH%;.;dir1;dir2 HelloWorld;
    

    三种基本的程序结构

    • 顺序结构
    • 选择结构
    • 循环结构

    使用这三种结构能编写出任意功能的程序。

    Java中的注释

    • 单行注释://
    • 多行注释:/**/
    • 文档注释:/** */ 使用javadoc可以生成api文档

    Java中的关键字

    Java中一共有48个关键字,2个保留字和三个直接量

    • 访问控制:private、protected、public;
    • 类,方法和变量修饰符:abstract、class、extends、final、implements、interface、native、new、static、strictfp、synchronized、transient、volatile;
    • 程序控制:break、continue、return、do、while、if、else、for、instanceof、switch、case、default;
    • 错误处理:try、cathc、throw、throws、finally;
    • 包相关:import、package;
    • 基本类型:boolean、byte、char、double、float、int、long、short、null、true、false;
    • 变量引用:super、this、void;
    • 保留字:goto、const;
    • 直接量:true、false、null。

    重要关键字说明:

    • native: 用来声明一个方法是由与机器相关的语言(如C/C++/FORTRAN语言)实现的;
    • strictfp:用来声明FP-strict(双精度或单精度浮点数)表达式;
    • transient:声明不用序列化的属性;
    • volatile:表明两个或多个变量必须同步地发生变化。

    数据类型

    Java中的数据类型分为基本数据类型和引用数据类型。

    数据类型

    1. 取值范围

    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位。

    需要注意的是:两个相同类型的数据相加后的值可能会超过其最大的取值范围,这边在我们开发过程中一定要注意~

    上面的float和double都是浮点类型数据,在计算机中,浮点数用来近似表示任意某个实数。浮点数分为双精度浮点数和单精度浮点数。单精度占4个字节,双精度占8个字节,表示的范围更大。

    对于double和float类型的数据,正数除以0得到正无穷,负数除以0得到负无穷,0.0除以0达到NaN。但是整数除以0会得到除0异常。

    在要求精确计算的场合,不建议使用浮点型数据。因为浮点数计算的结果不是很精确,是近似的结果。这种情况应该使用BigDecimal(或者金额用分作为单位,以Long存储)。这边举个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));
    

    2. 基本数据类型之间的转换

    char---------------|
    byte-->short-->int-->long-->float-->double

    对于上面的转换关系做下说明:char可以自动转换成int,byte可以自动转换成short,short可以自动转换成int。这些转换过程都是自动完成的。

    short a = 3;
    int b = a;
    

    那么将int赋值给short,或者将double赋值给int可不可以呢?答案是可以的,但是最后的数据可能不是我们预期的值。因为int占的字节数比short长,short盛放不下,会做数据截取。

    • 整数之间的强制转换:比如int转换为short会缩短位数;
    • double向int转换:会截掉小数部分。

    3. 表达式类型自动提升

    整个表达式的类型会提升为表达式中最高等级的类型。

    short aa = 1;
    //这个表达式会报错,aa+2会自动提升为int
    short bb = aa+2; 
    

    包装类类型

    包装类型是相对于基本数据类型来讲的。Java中有8种基本数据类型,每个基本数据类型都有相对的包装类型。比如int的包装类型是Integer。包装类型都是是引用类型,而且都是不可变类。

    关于包装类型,有两个概念需要我们了解:

    • 自动装箱:将基本数据类型赋值给包装类型的过程,实现原理是编译器层面new了一个包装类再赋值给相应的变量(如果是是将包装类缓存过的数值赋值给包装类的化,不会new新的包装了,而是直接使用缓存的对象);
    • 自动拆箱:包装类型直接赋值给基本数据类型,实现原理类似,也是编译器层面调用了包装类的getValue方法再赋值给对应的基本数值类型。

    比较有趣的是,包装类型在加载的过程中都会缓存某些值的类。比如Integer会缓存-128到127的类。

    //不会使用缓存的数据
    Integer num1 = new Integer(1); 
    //会使用缓存的数据,实际上是调用了Integer.valueOf方法
    Integer num2 = 1;
    

    通过设置-XX:AutoBoxCacheMax=?这个参数,可以调整Integer缓存的最大值。当然其他包装类型也有类似的行为,Byte、Short和Long都缓存了-128到127的类,Character缓存了0到127的类,但是这些类不能像Integer那样修改缓存的最大值。

    关于基本数据类型和包装类型的使用,介绍一个阿里巴巴开发规范中的原则:

    所有的POJO类属性必须使用包装数据类型;RPC方法的返回值和参数必须使用包装类型;所有的局部变量尽量使用基本数据类型。
    定义布尔型的类变量,变量名不要以is打头。

    Java中的值传递和引用传递

    基本数据类型,保存的是数据本身的值,按值传递;引用类型的变量保存的是对象在内存中的地址,按引用传递(引用传递可以看成是一种特殊的值传递)。

    成员变量和方法作用域

    对于成员变量和方法的作用域,有下面四种:

    • public : 表明该成员变量或者方法是对所有类或者对象都是可见的,所有类或者对象都可以直接访问;

    • private : 表明该成员变量或者方法是私有的,只有当前类对其具有访问权限,除此之外其他类或者对象都没有访问权限.子类也没有访问权限;

    • protected : 表明成员变量或者方法对类自身,与同在一个包中的其他类可见,其他包下的类不可访问,除非是他的子类;

    • default : 表明该成员变量或者方法只有自己和其位于同一个包的内可见,其他包内的类不能访问,即便是它的子类。

    一个问题

    Java中的bool变量到底占用多大的内存呢?网上的各种说法都有?欢迎大家留言讨论。

    公众号推荐

    欢迎大家关注我的微信公众号「程序员自由之路」

    人生的主旋律其实是苦难,快乐才是稀缺资源。在困难中寻找快乐,才显得珍贵~
  • 相关阅读:
    C 数组初始化
    Linux函数之snprintf()[一]
    出现一下错误
    IOS通过post方式发送图片续
    IOS通过post方式发送图片
    TCP和UDP的区别趣解
    [转]Release mode debugging with VC++
    [转]Math For Programmers
    OS:kernel and shell
    Reminder: 8020 rule
  • 原文地址:https://www.cnblogs.com/54chensongxia/p/13617401.html
Copyright © 2020-2023  润新知