Java基础

346 阅读21分钟

基础

注释

  1. 单行注释 // [代码]
  2. 多行注释 /* [代码] */
  3. JavaDoc文档注释 /** */

标识符

Java 所有的组成部分都需要名字。类名、方法名、变量名都被称为标识符

类名:在编程时为定义的对象取的名字,写在class后面
方法名: 方法是具有特定功能的一段代码,这段代码可以通过名字进行重复使用,类似C++中的函数
关键字:有特别意义的标识符。用来表示一种数据类型,或者表示程序的结构等

注意

  • 标识符必须仅包含字母,数字, $ 和 _
  • 首字符必须非数字
  • 区分大小写
  • 关键字不能用作变量名、方法名、类名、包名和参数。
  • 可以用中文命名,但不建议使用

数据类型

数据类型分为两大类:

1、基本数据类型:整型、浮点型、字符型、布尔型

整数类型 —— byte、short、int、long
浮点类型 —— float、double
字符类型 —— char
布尔类型 —— boolean

2、引用数据类型:接口(interface)、数组([ ])、类(class)

1.基本数据类型(八种):

1.1 整数类型

整型占用字节空间大小取值范围默认值
byte1字节-128 ~ 1270
short2字节-32768 ~ 327670
int4字节-2^31 ~ (2^31) - 10
long8字节-2^63 ~ (2^63) - 10L

Java默认 整型类型int
long类型要在数字后面加L(或l)
byte,short,int三种类型都是整型,因此如果操作整型数据时,最好统一使用int型

不同进制整数前缀:

  • 二进制 0b
  • 八进制 0
  • 十进制
  • 十六进制 0x
    • 0 ~ 9,A ~ F(10~15)

1.2 浮点类型(小数)

浮点型占用字节空间大小取值范围默认值
float4字节10^380.0F
double8字节10^3080.0

float类型要在数字后面加F(或f),否则就是double
浮点类型 位有限,有舍入误差,不能用来表示精确的值,如货币
最好避免使用浮点数进行比较

1.3 字符类型

字符型占用字节空间大小取值范围默认值
char2字节0 ~ 65535‘\u0000’与0

所有字符本质还是数字,二者通过 Unicode表 转化 (例如:97=a,65=A;u0061=a)

1.4 布尔类型

布尔型占用字节空间大小取值范围默认值
boolean1位,视情况而定true、falsefalse

逻辑上:1bit,但是实际上,boolean并没有具体规定,完全是看各个JVM实现

2.引用数据类型:

  • 引用数据类型建立在八大基本数据类型基础之上,包括类(class),接口(interface),数组(array) (枚举类型、注解类型、字符串(String)类型
    1. 字符串类型的数据都需要用双引号(")包围。在双引号之间的文本都被视为字符串
    2. 需要注意的是,单引号(')用于表示字符类型的数据,而不是字符串类型的数据
  • 引用数据类型是由用户自定义,用来限制其他数据类型。简单的说,除八大基本类型之外的所有数据类型,都为引用数据类型。

所有引用类型的默认值都为 null 。

拓展

单位

  1. 位(bit):
    又名 比特位,表示二进制位,是计算中内部 数据储存 的最小单位。一个二进制位只能表示0和1两种状态。如:11001100是一个八位二进制数。

  2. 字节(byte):
    是计算机中 数据处理 的基本单位。一个字节等于八位(1Byte = 8bit)。习惯上用大写B来表示。

  3. 字(word):
    计算机进行 数据处理 时,一次存取、加工和传送的数据长度。指计算机中使用的字母、数字、字和符号。在常见的计算机编码格式下,一个字等于两个字节(十六位)(1word = 2Byte = 16bit)

8b=1B,1024B = 1KB, 1024KB = 1M, 1024M = 1G,1024G=1T

float/double取值范围与精度

float的取值范围: -2128~−2−149、2 −149~2128、0、无穷大/小
double的取值范围: -21024~−2−1074、2 −1074~21024、0、无穷大/小
注意,浮点数是有精度的,并不能表示范围内的任意值

float的精度为有效小数位 6 ~ 7位,6位绝对精确,7位一般正确,8位可能正确(例如:8317637.5,其有效小数位:8.3176375E6,七位)
double的精度为有效小数位 15 ~ 16位,15位绝对精确,16位一般正确

转义字符

转义字符(ASCII码值【十进制】)意义
\b(008)退格(BS),将当前位置移到前一列
\f(012)换页(FF),将当前位置一道下页开头
\n(010)换行(LF),将当前位置移到下一行开头
\r(013)回车(CR),将当前位置移到本行开头
\t(009)水平制表(HT)(跳到次啊一个TAB位置)
\\(092)代表一个反斜字符\
\'(039)代表一个单引号(撤号字符)
\"(034)代表一个双引号字符
\?(063)代表一个问号
\0(000)空字符(NULL)
\ddd(三位八进制)1到3位 八进制数 所代表的任意字符
\xhh(十六进制)十六进制所代表的任意字符

类型转换

由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换

在Java中整型、实型、字符型被视为简单数据类型,这些类型由低级到高级分别为byte,short,char(三者同级)→ int → long → float → double

简单数据类型之间的转换又可以分为:

  • 低级到高级 的 自动类型转换
  • 高级到低级 的 强制类型转换

1. 低级到高级的自动类型转换,例如,下面的语句可以在Java中直接通过:

  byte b;
  int i=b;  long l=b;  float f=b;  double d=b;

低级类型 char型,向高级类型 整型转换时,会转换为对应ASCII码值,例如

char c = 'a';//a对应ASCII码值为 97
int n = c+1; 
System.out.println(n); //输出:98 

2. 平级的 byte,short,char 相互转换;高级变量转换为低级变量。必须采用下述的强制类型转换语句格式,即,在被转换的数据类型前加上 ( [目标数据类型] )

short i=99;
char c=(char)i;
System.out.println("output:" c);
//输出:output:c;

byte b=(byte)i;
char c=(char)i; 
float f=(float)i;

但是,这种转换可能会导致内存溢出或精度丢失

精度丢失

System.out.println((int)23.7); //输出:23 丢失精度

溢出问题及其解决方法

当操作数比较大时,注意溢出问题

int money = 10_0000_0000; //JDK7新特性,数字之间可以用下划线分割,下划线不会被打印出来
System.out.println(money); //输出:1000000000
int years = 20;

int total = money*years;  //数据大,溢出
System.out.println(total); //输出:-1474836480

long total2 = money*years; //计算结果是int,即溢出,转换前就有溢出问题
System.out.println(total2); //仍输出:-1474836480

long total3 = money*(long)years; //先把一个数转Long
System.out.println(total3); //输出:20000000000,结果为Long
  • 不能对布尔值进行转换

变量、作用域、常量

变量

Java变量是程序中最基本的存储单元,要素包括变量名、变量类型和作用域

Java是一种强类型语言,每个变量都必须声明其类型,定义语法如下:

//数据类型 变量名 = 值;
type variable = value;

//连续定义多个变量
int a = 1,b = 3,c = 10
//进一步简化
int a,b,c = 10;

//可以使用逗号隔开同多个类型的变量,但不建议在一行定义多个变量

变量作用域

类变量(也叫静态变量,static)
定义语法:static+数据类型+变量名
作用域:整个类的生命周期

实例变量
从属于类对象
作用域:整个类对象的生命周期:从实例化到被回收
可以不初始化,系统会赋初始值。数值类型默认值为0,boolean类型默认值为false,除了基本类型外其他类型默认值为null

局部变量
指在方法或者方法代码块中定义的变量,其作用域是其所在的代码块。分为三种:

  1. 方法参数变量(形参):在整个方法内有效;
  2. 方法局部变量(方法内定义): 从定义这个变量开始到方法结束这一段时间内有效;
  3. 代码块局部变量(代码块内定义):从定义这个变量开始到代码块结束这一段时间内有效;

局部变量除了形参外,都需要指定一个初始值,否则无法访问;

常量

初始化后不再改变的值。定义语法如下:

final 数据类型 常量名称 = 值;

例如:
public static final doube PI=3.14;
//public static final 是修饰符 不存在先后顺序

标识符命名规范

  • 见名知意
  • 常量名:单词字母均大写,单词之间用下划线 _ 连接:MAX_VALUE
  • 类名:大驼峰法:Man,GoodMan(驼峰原则:单词的首字母均大写)
  • 类成员变量名:小驼峰法
  • 局部变量名:小驼峰法
  • 方法名:小驼峰法
  • 避免使用Java保留字

当命名需要由一个或多个单词连结在一起,构成的唯一识别字时,有以下两种驼峰命名法供选择

小驼峰法:除第一个单词之外,其他单词首字母大写
大驼峰法:每个单词的首字母都大写

运算符

  1. 算术运算符:+(加),-(减),* (乘),/(除),%(取余),++(自增),--(自减)
  2. 赋值运算符:=(等于),+=(自加一次等于),-=(自减一次等于),* =(自乘一次等于),/=(自除一次等于),+(字符串连接符)
    +=、-=、*=、/=、%=表示的意思是先将运算符左边变量值右边的数相加(减、乘、除、取余),然后将结果赋值给左边的变量
  3. 比较运算符:>(大于),<(小于),>=(大于等于),<=(小于等于),==(比较等于),!=(不等于)
    返回结果只有:true或false
  4. 逻辑运算符:&(按位与),&&(短路与),|(按位或),||(短路或),!(非,即取反)
  5. 条件(三目、三元)运算符:?:
  6. 位运算符(都是基于二进制来计算):&(按位与),|(按位或),^(异或运算),<<(左移运算符),>>(右移运算符),>>>(无符号运算符),~(非、取反运算符)
  7. 自增自减运算符:++(自增),--(自减)

自增自减运算符

  • 自增运算符为 ++ ,其功能是使变量的值自增1
  • 自减运算符为 -- ,其功能是使变量的值自减1

如果想要将一个数自增/减,但现在先使用其自增/减之前的值,那么需要使用后置形式

在非循环语句中:执行完 使用其自增/减之前的值 的语句,值才会增/减
在循环中:执行完当前循环,值才会增/减

拓展

笔试题 i=5 s=(i++)+(++i)+(i--)+(--i) s=?

int i=5; 
int s=(i++)+(++i)+(i--)+(--i); 
System.out.println(s); //24

逐步分解这个表达式:

  1. (i++):这里先使用 i 的当前值(5),然后再将 i 的值加 1。
  2. (++i):在上一步执行完之后,i 的值已经变成了 6,所以这里先将 i 的值加 1,然后再加到结果中。
  3. (i--):现在 i 的值是 7,所以我们可以将它添加到结果中,然后再将 i 的值减 1。
  4. (--i):最后,将 i 的值减 1,然后再将其添加到结果中。
  5. 因此,s 最终的值为 24。

一个算式中,多个不同类型的数据混合运算,运算结果的数据类型为其中类型等级最高的

字符串连接符

在 “ + ” 运算中,两边的操作数都是数字,则进行求和运算;只要两边其中有一个操作数是字符串类型,则将数字转化为String类型,进行字符串拼接运算,字符串拼接之后的结果还是字符串类型。

注意,当一个表达式当中有多个 “ + ”,并且在没有小括号的前提下,遵循自左向右的顺序依次执行
以下面代码为例:

int a = 10; 
int b = 20;
System.out.println(""+a+b); //1020 
System.out.println(a+b+""); //30 先a+b进行求和运算,再转为String拼接 
System.out.println(a+b+"str"); //30str

逻辑运算符

特点是操作数都是布尔类型,并且最终的运算结果也是布尔类型

  • 与运算 &&

参与运算的两个变量都为真时,结果才为真,否则为假。例如:5>=5 && 7>5 ,运算结果为真;

  • 或运算 ||

参与运算的两个变量只要有一个为真,结果就为真。 两个量都为假时,结果为假。例如:5>=5||5>8,运算结果为真;

  • 非运算 !

参与运算的变量为真时,结果为假;参与运算量为假时,结果为真。例如:!(5>8),运算结果为真。
对变量取逻辑非操作,得到的结果是:
如果变量的值为0,则取非后结果为1;
如果变量的值不为0,则取非后结果为0。

短路

逻辑与 &&、逻辑或 || 均有“短路”特性:
逻辑与&&“短路”:左边不成立时编译器不计算右边
逻辑或||“短路”:左边成立时编译器不计算右边

注意:如果 &、|、^ 这三个运算符两边是数值则为位运算符,如果两边是 boolean 类型值则作为逻辑运算符。

位运算符

位运算符:进行的操作都是二进制的,也就是说在操作之前需要先把数据转换为二进制数。

注意:如果 &、|、^ 这三个运算符两边是数值则为位运算符,如果两边是 boolean 类型值则作为逻辑运算符。

位运算符&、|、^、~ 的功能

以下面代码为例:

public class Test {

    public static void main(String[] args) {
        //(int类型的值占4个字节,32位二进制数)
        int a = 3; //3 的二进制数 00000000 00000000 00000000 00000011
        int b = 4; //4 的二进制数 00000000 00000000 00000000 00000100

        System.out.println(a & b);
        System.out.println(a | b);
        System.out.println(a ^ b);
        System.out.println(~a);
    }
}

& 运算符:有0则0

3 & 4为例

  00000000  00000000  00000000  00000011
& 00000000  00000000  00000000  00000100
------------------------------------------
  00000000  00000000  00000000  00000000   	--也就是十进制的 0

| 运算符:有1则1

3 | 4为例:

  00000000  00000000  00000000  00000011
| 00000000  00000000  00000000  00000100
------------------------------------------
  00000000  00000000  00000000  00000111		--也就是十进制的 7

^ 运算符:相同则0,不相同则1

3 ^ 4为例:

  00000000  00000000  00000000  00000011
^ 00000000  00000000  00000000  00000100
------------------------------------------
  00000000  00000000  00000000  00000111		--也就是十进制的7

~ 运算符:按位取反

~ 3为例:

~ 00000000  00000000  00000000  00000011
------------------------------------------
  11111111  11111111  11111111  11111100        --这里得到的是最后结果的补码

  11111111  11111111  11111111  11111011        --最后结果的反码
  10000000  00000000  00000000  00000100	      --最后结果的原码,最后结果即十进制的 -4

位运算符 &、| 没有“短路”特性
无论结果,所有的都运行

//逻辑与 所有的都运行
int a = 10; 
int b = 4;  
if (a > 100 & (b++) <5){
} 
System.out.println(b); //结果为 5,b++运行了

位运算符 <<、>>、>>> 的功能 

以下面代码为例:

public class Test {

    public static void main(String[] args) {
        int a = 16;

        System.out.println(a << 2);
        System.out.println(a >> 2);
        System.out.println(-16 >> 2);
        System.out.println(a >>> 2);
    }
}

16 的二进制数:

00000000  00000000  00000000  00010000

<< 运算符:把数据向左移动指定位数,右边补0,相当于乘以 2 的 [移动位数] 次幂。
16 << 2为例:

          00000000  00000000  00000000  00010000
      (00)000000  00000000  00000000  000100000000000000  00000000  00000000  01000000  		 --也就是十进制的 64

>> 运算符(有符号右移)

  • 正数右移:把数据向右移动指定位数,左边补0,相当于除以 2 的 [移动位数] 次幂。
    16 >> 2 为例:
  	 00000000  00000000  00000000  00010000
  	 0000000000  00000000  00000000  000100(00)
        即 00000000  00000000  00000000  00000100			--也就是十进制的 4
  • 负数右移:把数据向右移动制定位数,左边补1,相当于除以 2 的 [移动位数] 次幂。
    操作:负数 先求得负数的补码,再对其进行移位操作
    -16 >> 2 为例:
  10000000  00000000  00000000  00010000   		--16 的二进制原码
  11111111  11111111  11111111  11101111   		--16 的反码(负数符号位不变,其他位取反)
  11111111  11111111  11111111  11110000   		--16 的补码(反码加 111111111  11111111  11111111  11111100(00)   		--对其补码进行右移2位 —— 即,移位后的补码
  11111111  11111111  11111111  11111011   		--将 移位后的补码 -1 —— 即,移位后的结果数的反码
  10000000  00000000  00000000  00000100   		--取反,得到原码(负数符号位不变,其他位取反)
                                                          --这个就是最终的结果的二进制数,即为十进制的 -4

补充:正数的原码、反码、补码相同。

>>> 运算符(无符号右移)

无论是正数还是负数,把数据向右移动指定位数,左边补0,相当于除以 2 的 [移动位数] 次幂。(类似于正数的右移)

拓展

面试题:2*8 怎么算最快?

2<<3 <<左移 *2 效率极高!!

三元运算符

语法:变量=[条件]?expression1:expression2

如果条件返回true,则执行expression1,否则执行expression2,并将最终结果存储在变量中

执行expression n就相当于用表达式n代替整个三元运算结构

运算符优先级

优先级运算符结合性
1()、[]、{}从左向右
2!、+正、-负、~、++、--从右向左
3*、/、%从左向右
4+、-从左向右
5<<、>>、>>>从左向右
6<、<=、>、>=、instanceof从左向右
7==、!=从左向右
8&从左向右
9^从左向右
10|从左向右
11&&从左向右
12||从左向右
13? :从右向左
14=、+=、-=、*=、/=、&=、|=、^=、~=、<<=、>>=、>>>=从右向左

包机制

包可以被看作是一个文件夹,通过将类放置在特定的包内,可以将其组织在一起,并提供更好的可读性和可维护性。同时,包也有助于控制类的访问权限,提供了更好的封装性。

包的定义通常由包名和包声明语句组成:

  • 包名:包名使用小写字母,并以域名反转的形式作为前缀。例如,com.kuangstudy.www。包名应该具有唯一性,以确保不同组织之间的包名不冲突。
  • 包声明语句:在 Java 源文件的开头,使用 package 关键字来声明类所属的包。例如,package cn.zwz.test;,包声明语句必须位于源文件的开头,任何其他代码之前,且只能出现一次。
    语法格式:
package pkg1[.pkg2[.pkg3...]];

包的导入 在 Java 中,可以使用 import 语句将其他包中的类引入到当前源文件中,以便在代码中直接使用这些类而无需使用完全限定名。

语法格式:import package1[.package2...].(className|*); //通配符* 导入包下所有的类

以下是Java包导入的方式:

导入单个类:

import cn.zwz.test.MyClass;

这将导入包 cn.zwz.test 中的类 MyClass,可以在当前源文件中直接使用 MyClass 类。

导入整个包:

import cn.zwz.test.*;

使用通配符 * 可以导入包中的所有类。这意味着可以直接使用该包中的所有类。

注意:使用通配符导入整个包可能会导致名称冲突问题,在导入时要小心,确保没有类名冲突

JavaDoc生成文档

JavaDoc是一种用于编写和生成Java代码文档的工具。来描述 类、方法、接口和其他代码元素,并生成相应的的文档

JavaDoc注释以"/**"开始,"*/"结束,可以包含丰富的参数信息,它允许开发者通过在源代码中添加特定格式的注释用于描述方法的参数、返回值以及可能抛出的异常,包括类的说明、方法的说明、参数说明等。这些参数信息会被JavaDoc工具识别并转换成相应部分的HTML格式文档,以便其他开发者能够更轻松地理解和使用这些代码。

总之,JavaDoc是Java开发中非常重要的文档工具,能够帮助开发者更好地组织和展示代码的文档信息,提高代码的可理解性和可维护性。

  • 参数信息
    • @author 作者名
    • @version 版本号
    • @since 指明最早用的jdk版本
    • @param 参数名
    • @return 返回值情况
    • @throws 异常抛出情况

命令行生成JavaDoc文档

  1. 在cmd中进入 .java文件的地址
  2. 输入格式:javadoc [参数] Java文件,例如:javadoc -encoding UTF-8 -charset UTF-8 Doc.java,其中参数是为了编译中文
  3. 会自动生成该类有关的API文档,查看文件夹发现多了一些文件
  4. 打开 index.html(首页)查看文档注释

IDEA生成JavaDoc文档

  1. 工具栏中点击Tools,打开选项Generate JavaDoc
  2. 选择生成JavaDoc文档的对应文件
  3. 选择存放JavaDoc文档的文件夹
  4. 选择文档语言,简体中文就是zh_CN、繁体(台湾)zh_tw、繁体(香港)zh-hk、英语(香港)en-hk、英语(美国)en-us、英语(英国)en-gb、英语(全球)en-ww
  5. 设置编码,为了使显示的中文不出现乱码 -encoding UTF-8 -charset UTF-8

设置完即可生成doc文档