我喜欢你眼中的星辰,喜欢你轻唤我的名字

Java基础


Java基础

注释

java中有三种注释:单行注释、多行注释和文档注释

  • 单行注释 // 这是单行注释
  • 多行注释 /*这是多行注释*/
  • 文档注释(Javadoc) /**这是文档注释*/

文档注释只能放在类、接口、方法、构造器、成员字段之前,由描述部分和标记部分组成,描述部分和标记部分之间通过空行区分,是专门为javadoc工具自动生成文档而写的注释

里面含有一些特殊标签(简单列举):

标签 描述 范围 示例
@author 作者 文件、类、方法 @author remmeiko
@since JDK版本 文件、类 @since 1.8
@version 软件版本号 文件、类、方法 @version 1.0.0
@param 方法参数 方法 @param 参数名称 参数描述
@return 方法返回值 方法 @return 返回值描述

程序中的文档注释遵守一定的规范,便可以通过Javadoc工具从源代码中抽取这些注释生成API帮助文档,Java帮助文档主要用来说明类、成员变量和方法的功能

使用Javadoc工具生成帮助文档: javadoc -encoding UTF-8 -charset UTF-8 java.java

使用Intellij开发工具:Tools–>Generate JavaDoc–>Other command line arguments输入-encoding UTF-8 -charset UTF-8设置编码格式–>确定

写程序必须养成写注释的习惯,注释是程序的规范之一

标识符和关键字

标识符

Java语言中,类、接口、变量、常量、函数、语句块等名字统称为Java标识符,说白了就是Java语言中自己命名的名字。

String name = "remmeiKo"

在这个里面name就是标识符

命名约定

  • 标识符可以是字母(a-z,A-Z),$符号或者下划线(_)或者数字的任何组合,但是数字不能作为标识符的开头
    • 比如2u_d,u_d¥是非法的,u_d,u_d$是合法的标识符
  • 标识符是大小写敏感的
  • 不能使用关键字作为名字(方法名、变量名等)
  • 命名应该尽量使用英文并且做到见名知意

关键字(保留字)

Java中具有特殊含义的标识符,不能用来作为方法名、包名等使用

关键字

在使用过程中会逐渐熟悉

数据类型

Java是一种强类型语言,其数据类型有两种,基本类型(primitive type)和引用类型(reference type),第一次申明变量时必须申明变量类型

强类型语言:强弱类型这个东西比较抽象和复杂,众说纷纭,百度百科说的是强类型指的是程序中表达的任何对象所从属的类型都必须能在编译时刻确定,任何变量在使用时必须指定该变量的类型,不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。

按照百度百科通俗理解的是Java应该是弱类型语言。所以我的理解就是倾向于类型转换的是弱类型语言,反之则是强类型语言。像弱类型语言类型转换是很随意的,布尔类型和其他类型也能相互转换。

基本数据类型

也被成为内置类型

  • 整数型
    • byte,占用1个字节,范围:-128-127
    • short,占用2个字节,范围:-32768-32767
    • int,占用4个字节,范围:-2147483648-2147483647(20亿左右,一般整数使用int就够了)
    • long,占用8个字节,范围:-2^31~2^31-1
  • 浮点型
    • float,占用4个字节
    • double,占用8个字节
  • 字符类型
    • char,占用2个字节
  • 布尔类型
    • boolean,只有如果虚拟机的实现按照规范来则在数组情况下占用1个字节,单个占用4个字节

二进制的前缀是0b

八进制的前缀是0

十六进制的前缀是0x

比如2分别用二进制,八进制,十六进制表示是0b10,002 0x02

布尔类型扩展

if(flag == true) 和 if(flag)尽量采用后者

关于布尔类型的大小有几种说法;

  • 1个bit位
  • 1个字节
  • 4个字节

布尔类型只有true和false两个可能的值,也就是真和假,那么用0和1来表示就可以了,也就是说用一个bit位就足够了,但是计算机处理数据的最小单位是1个字节,(计算机寻址操作以字节为最小单位进行)也就是说实际存储的空间需要一个字节。别急,接着往下看:

在《虚拟机规范》中对于布尔类型有专门的解释:“虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,(因此)每个boolean元素占8位”

也就是说在数组情况下占用1个字节,单个占用4个字节

这里要说一点,世界上制作了Java虚拟机(JVM)的除了Oracle公司还有许多公司,详情可以看维基百科JVM比较,意思就是因为虚拟机的不同因此情况也可能需要另作讨论

最后的结论就是:如果虚拟机遵守《虚拟机规范》,在数组情况下布尔类型占用1个字节,单个占用4个字节

浮点型扩展

银行家业务,对于精确度高的场景使用大数类型,浮点型会出现舍入误差

先提一个问题:0.1+0.2=?

这句话会打印什么:System.out.println(0.1+0.3);

打印结果

打印出来的并不是0.3,为什么会这样?

浮点数的存储

IEEE754标准中浮点数表示法是一种科学计数法,组成分为三部分:

  • 符号位(sign),用来区分浮点数的正负,0表示正数,1表示负数

  • 指数位(exponent):用来存储指数,范围是0-255,因为指数可能为负数,为此实际指数位存储的是指数减去偏移量(需要转换成二进制)

  • 尾数位(fraction):保存尾数(这个尾数不仅包括小数部分)

Type 符号位 指数位 尾数位 偏移量 总位数
float 1位 8位 23位 127 32位
double 1位 11位 52位 1023 64位

科学计数法:举例–0.00213 科学计数法为2.13*10^-3 这里5是指数

浮点数也是一样,采用的是二进制,如采用二进制来表示整数和小数,举例100.10101—->科学计数法就是1.0010101*2^2

这里指数就是2,将其加上偏移量转换成二进制便得到了指数位

科学计数法中小数点后的便是尾数位,需要注意的是浮点型的尾数位数,当超过这个位数后便会直接截断舍去,这也是造成误差的原因。

存储计算

以2.3这个小数为例,这里采用的是float型,我们计算一下在计算机中是如何以二进制存储的。

符号位:0 因为是正数

先将其化为二进制(乘2除整):10.01001100110011001100110 (这里只取23位)

2 –> 10

0.3 –> 01001100110011001100110

再将其转换成科学计数:1.0010_0110_0110_0110_0110_011 * 2^1

我们看到其指数为1,将其加上偏移量127后为128,二进制是1000_0000,因此指数位为1000_0000

小数位:0010_0110_0110_0110_0110_011

最后结果:0 1000_0000 0010_0110_0110_0110_0110_011

误差原因

当我们把小数转换成二进制的时候,很多时候得到的是一个二进制无限循环小数,但是我们的浮点型对于尾数的位数却是有限的,当超过这个位数后面的数据便会被舍去,float的尾数是23位,double的尾数是52位,double比float精确度要高很多,但也是存在误差的,0.1+0.2!=0.3的前提是使用double型。

二进制可以精确的表示位数有限并且分母是2的倍数的小数

注意
  • 对于精确度比较高的项目或者场景就不能使用浮点型,浮点型会出现舍入误差例如银行业务这些,可以使用大数类或者其他工具类
  • 绝不能将浮点变量用”==”或”!=”与任何 数字进行比较

推荐个网址:https://babbage.cs.qc.cuny.edu/ieee-754.old/decimal.html

引用数据类型

  • String字符串属于对象类型
  • 基本数据类型之外的所有数据都属于引用数据类型
  • 两个String字符串对象比较需要从内存进行分析,会在后续完善中补上

类型转换

  • 在运算过程中,所有不同类型的数据会先转换成同一类型,然后进行转换
  • 在Java中,整数默认类型是int,浮点型默认类型是double

所有基本类型按照所占空间大小进行比较:

低–>高

byte–>char,short–>int–>long

float–>double

注意

  • char是16位无符号Java基元数据类型,范围是0-65536,没有负数,因此byte,short不能自动转换为char

  • 整数类型可以自动转换成浮点类型,浮点类型转换成整数类型需要强转

强制转换

高类型 –> 低类型

int a = 12; byte b = (byte)a

自动转换

低类型 –> 高类型

转换注意

  1. 不能对布尔类型进行转换
  2. 不能把对象类型转换成不相干的类型
  3. 强制转换时可能存在内存溢出和精度损失
  4. 高容量转换成低容量时必须使用强制转换
  • 注意long类型规范使用L而不是l更加直观

变量、常量、作用域

常量和变量在空间分配上有很大的区别,后续详细讲解

变量

Java变量是程序中最基本的存储单元,其包括变量名,变量类型和作用域,在Java中分为类变量,实例变量,局部变量等

public class Test {
    static final String name = "remmeiko";//类变量
    int age = 12;//实例变量
    //数据类型 变量名 = 数据
    public void method() {
        int i = 0;//局部变量
    }
}

实例变量:属于对象,具有默认值

static、final等修饰符不存在先后顺序

常量(Constant)

  • 常量名一般使用大写字符

  • 是一种特殊的变量,它的值被设定后,在程序运行过程中不允许改变

基本运算符

运算符名称 运算符
算数运算符 +,-,*,/,%,++,–
赋值运算符 =
关系运算符 >,<,>=,<=,==,!instanceof
逻辑运算符 &&,||,!
位运算符 &,|,~,>>,<<,>>>
条件运算符 ?:
扩展赋值运算符 +=,-=,*=,/=

++ – 也被称为一元运算符

包机制

一般使用公司域名倒置作为包名,是用来区分类名的命名空间

package com.remmeiko.www;

import java.util.*;// 导入包

References

你知道Java语言布尔(boolean)型数据到底占多大空间吗?

为什么0.1+0.2不等于0.3

java浮点类型float和double的主要区别,它们的小数精度范围大小是多少?


文章作者: RemMeiko
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 RemMeiko !
评论
  目录