Java基础
注释
- 平时我们编写代码,在代码量比较少的时候,我们还可以看懂自己写的,但是当项目结构一旦复杂起来,我们就需要用到注释了
- 注释并不会被执行,是给我们写代码的人看的
- 书写注释是一个非常好的习惯
Java中的注释有三种
- 单行注释
- 多行注释
- 文档注释
public class HelloWorld { //类
public static void main(String[] args) { //方法
String people = "空白名Tee"; //定义变量
System.out.println("Hello,World!"); //输出Hello,World!
}
//有趣的代码注释
/***
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ____/`---'\____
* . ' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
*
* .............................................
* 佛祖保佑 永无BUG
*/
//多行注释 /* 注释 */
/*
我是多行注释
我是多行注释
我是多行注释
*/
//JavaDoc:文档注释 /** 注释 */
/**
* @Description Hello,World
* @Author 空白名Tee
*/
}
标识符
-
关键字
Java所有的组成部分都需要名字;类名、变量名以及方法名都被称为标识符
关键字 含义 abstract 表明类或者成员方法具有抽象属性 assert 断言,用来进行程序调试 boolean 基本数据类型之一,声明布尔类型的关键字 break 提前跳出一个块 byte 基本数据类型之一,字节类型 case 用在switch语句之中,表示其中的一个分支 catch 用在异常处理中,用来捕捉异常 char 基本数据类型之一,字符类型 class 声明一个类 const 保留关键字,没有具体含义 continue 回到一个块的开始处 default 默认,例如,用在switch语句中,表明一个默认的分支。Java8 中也作用于声明接口函数的默认实现 do 用在do-while循环结构中 double 基本数据类型之一,双精度浮点数类型 else 用在条件语句中,表明当条件不成立时的分支 enum 枚举 extends 表明一个类型是另一个类型的子类型。对于类,可以是另一个类或者抽象类;对于接口,可以是另一个接口 final 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量 finally 用于处理异常情况,用来声明一个基本肯定会被执行到的语句块 float 基本数据类型之一,单精度浮点数类型 for 一种循环结构的引导词 goto 保留关键字,没有具体含义 if 条件语句的引导词 implements 表明一个类实现了给定的接口 import 表明要访问指定的类或包 instanceof 用来测试一个对象是否是指定类型的实例对象 int 基本数据类型之一,整数类型 interface 接口 long 基本数据类型之一,长整数类型 native 用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的 new 用来创建新实例对象 package 包 private 一种访问控制方式:私用模式 protected 一种访问控制方式:保护模式 public 一种访问控制方式:共用模式 return 从成员方法中返回数据 short 基本数据类型之一,短整数类型 static 表明具有静态属性 strictfp 用来声明FP_strict(单精度或双精度浮点数)表达式遵循[IEEE 754](https://baike.baidu.com/item/IEEE 754)算术规范 super 表明当前对象的父类型的引用或者父类型的构造方法 switch 分支语句结构的引导词 synchronized 表明一段代码需要同步执行 this 指向当前实例对象的引用 throw 抛出一个异常 throws 声明在当前定义的成员方法中所有需要抛出的异常 transient 声明不用序列化的成员域 try 尝试一个可能抛出异常的程序块 void 声明当前成员方法没有返回值 volatile 表明两个或者多个变量必须同步地发生变化 while 用在循环结构中 ——[百度百科](java关键字_百度百科 (baidu.com))
标识符注意点
- 所有的标识符都应该以字母(A-Z或者a-z),美元符($),或者下划线(_)开始
- 首字符之后可以是字母(A-Z或者a-z),美元符($),或者下划线(_)或数字的任何字符组合
- 不能使用关键字作为变量名或方法名
- 标识符是大小写敏感的
- 合法标识符举例:age、$salary、_value、__1_value
- 非法标识符举例:123abc、-salary、#abc
- 可以使用中文命名,但是一般不建议这样去使用,也不建议使用拼音
ctrl+d快速复制当前行
数据类型
-
强类型语言
- 要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用
-
弱类型语言
-
Java的数据类型分为两大类
- 基本类型(primitive type)
- 引用类型(reference type)
public class Demo02 { public static void main(String[] args) { //整数 int num = 10; //最常用 byte num1 = 20; short num2 = 30; long num3 = 30L; //Long类型要在数字后面加个L //小数:浮点数 float num4 = 50.1F; //float类型要在数字后面加个F double num5 = 3.1415926; //字符 char name = '我'; //字符串,String不是关键字,它是一个类 String namea = "我真厉害"; //布尔值 boolean flag = true; //或boolean flag = false; } }
数据类型扩展
-
整数拓展
二级制0b开头,八进制0开头,十六进制0x开头
public class Demo03 { public static void main(String[] args) { //整数拓展 进制:二进制0b开头,八进制0开头,十进制,十六进制0x开头 int i = 10; //十进制 int i1 = 0b10; //二进制 int i2 = 010; //八进制0 int i3 = 0x10; //十六进制0x 0~9 A~F System.out.println(i); System.out.println(i1); System.out.println(i2); System.out.println(i3); } }
看一下运行结果,不同进制表示的数是不一样的
-
浮点数扩展
银行的业务怎么表示?
Java中,浮点数是存在问题的,做个实验验证一下,看一下结果
public class Demo04 { public static void main(String[] args) { float f = 0.1F; //0.1 double d = 1.0/10; //0.1 System.out.println(f==d); System.out.println(f); System.out.println(d); float d1 = 384617868718f; float d2 = d1 + 1; System.out.println(d1==d2); } }
上面的数据相等,但判断结果却不相等,下面的数据不相等,判断结果却相等;浮点数表现的数是有限且离散,存在舍入误差,就是四舍五入,结果只能是一个大约数
最好避免是浮点数进行比较,银行的业务可以使用BigDecimal数字工具类表示
-
字符拓展
所有字符本质是数字,字符是可以强制转换成数字的;所有的字符都可以在Unicode编码(占2字节)表中找到,例如97=a,65=A,表中的原始数据表现形式为U0000~UFFFF
public class Demo05 { public static void main(String[] args) { char c1 = 'a'; char c2 = '中'; System.out.println(c1); System.out.println((int)c1); //强制转换 System.out.println(c2); System.out.println((int)c2); //强制转换 char c3 = '\u0061'; System.out.println(c3); //输出结果a } }
还有一种是转移字符
所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加""来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。
所有的转义字符和所对应的意义:
转义字符 意义 ASCII码值(十进制) \a 响铃(BEL) 007 \b 退格(BS) ,将当前位置移到前一列 008 \f 换页(FF),将当前位置移到下页开头 012 \n 换行(LF) ,将当前位置移到下一行开头 010 \r 回车(CR) ,将当前位置移到本行开头 013 \t 水平制表(HT) (跳到下一个TAB位置) 009 \v 垂直制表(VT) 011 \ 代表一个反斜线字符’’\’ 092 ’ 代表一个单引号(撇号)字符 039 " 代表一个双引号字符 034 ? 代表一个问号 063 \0 空字符(NUL) 000 \ddd 1到3位八进制数所代表的任意字符 三位八进制 \xhh 十六进制所代表的任意字符 十六进制 注意:
区分,斜杠:"/" 与 反斜杠:"\" ,此处不可互换
\xhh 十六进制转义不限制字符个数 ‘\x000000000000F’ == ‘\xF’
\x表示后面的字符是十六进制数,\0表示后面的字符是八进制数
public class Demo05 { public static void main(String[] args) { System.out.println("Hello\nWorld!"); //换行符 System.out.println("Hello\tWorld!"); //水平制表符 } }
-
布尔值扩展
if (flag==true){}
if (flag){}
这两行代码意思是一样的,代码要精简易读
public class Demo01 { public static void main(String[] args) { boolean flag = true; if (flag==true){} if (flag){} //代码要精简易读 } }
-
类型转换
-
由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换
低------------------------------------>高 //容量大小 byte,short,char->int->long->float->double //小数优先级一定大于整数
-
运算中,不同类型的数据先转换为同类型,然后进行运算
-
强制转换
在把高容量转换到低容量的时候,强制转换
public class Demo06 {
public static void main(String[] args) {
//强制转换
int i = 128;
byte b = (byte) i; //内存溢出
System.out.println(i);
System.out.println(b);
//byte最大值是127,赋值128,超过了最大值
}
}
强制转换代码没问题,但结果却不同,因为byte最大值是127,赋值128超过了最大值,这个时候就会出现内存溢出
- 自动转换
在把低容量转换到高容量的时候,自动转换,自动转换可以直接转换
public class Demo06 {
public static void main(String[] args) {
//自动转换
int i = 128;
double b = i;
System.out.println(i);
System.out.println(b);
}
}
运行结果没有问题,double是小数,所以是128.0
-
浮点数转换
浮点数转换时可能会出现精度问题,默认向0取整
public class Demo07 { public static void main(String[] args) { System.out.println((int)23.7); System.out.println((int)-45.89F); //向0取整 } }
-
其它技巧
JDK7新特性,数字之间可以用下划线分割,且下划线不会输出
public class Demo08 { public static void main(String[] args) { int money = 10_0000_0000; System.out.println(money); } }
还有一个问题
public class Demo08 {
public static void main(String[] args) {
int money = 10_0000_0000;
System.out.println(money);
int years = 20;
long total = money*years;
System.out.println(total);
}
}
数据类型默认是int,转换long类型之前就存在问题了,因为是先计算,再转换,此时结果就会出现问题,即溢出
如何解决这个问题,只要在计算前先转换再计算就可以了
public class Demo08 {
public static void main(String[] args) {
int money = 10_0000_0000;
System.out.println(money);
int years = 20;
long total = money*years;
long total2 = money*((long)years);
System.out.println(total);
System.out.println(total2);
}
}
此时结果就没有问题了
注意点
1. 不能对布尔值进行转换
2. 不能把对象类型转换为不相干的类型
3. 在把高容量转换到低容量的时候,强制转换,反之自动转换
4. 转换的时候可能存在内存溢出,或者精度问题
变量
- 变量是什么:就是可以变化的量!
- Java是一种强类型语言,每个变量都必须声明其类型
- Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域
type varName [=value] [{,value[=value]}];
//数据类型 变量名 = 值;可以使用逗号隔开来声明多个同类型变量 不建议一行定义多个同类型变量,可读性差
- 注意事项
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型
- 变量名必须是合法的标识符
- 变量声明是一条完整的语句,因此每一个声明都必须以分号结束
变量作用域
- 类变量
- 实例变量
- 局部变量
public class Variable{
static int allClicks=0; //类变量
String str = "Hello World!"; //实例变量
public void method(){
int i = 0; //局部变量
}
}
-
局部变量只在main方法范围内有用,且必须声明和初始化值
public class Demo09 { //main方法 public static void main(String[] args) { // //局部变量,只在这个范围内有用,且必须声明和初始化值 int i = 10; System.out.println(i); } // }
输出结果都没有问题
如果跳出这个范围,就无法使用;打个比方,将输出i这个命令放到main方法外,程序直接爆红,且运行结果出错
-
实例变量在方法的外面,类的里面,如果方法需要使用这个数值,则必须在方法里调用
//类 public class Demo10 { //实例变量:从属于对象 String name; int age; //main方法 public static void main(String[] args) { //变量类型 变量名字 = new 变量名字(); Demo10 demo10 = new Demo10(); System.out.println(demo10.name); System.out.println(demo10.age); } }
同理,如果不先调用,会直接爆红且运行出错
因为没有对变量赋值,因此输出结果均为默认值:
-
所有的数值类型默认值为0,0.0,u0000
-
布尔值默认值是false
-
除了基本类型,其余的默认值都是null
-
-
类变量与实例变量一样位置,不过要加入一个static命令,且方法里可以直接使用
//类 public class Demo11 { //类变量,从属于类 static double salary = 2500; //main方法 public static void main(String[] args) { System.out.println(salary); } }
同理,删除static运行出错
常量
-
常量(Constant):初始化(initialize)后不能再改变值!不会变动的值
-
所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变
final 常量名=值; final double PI=3.14;
-
常量名一般使用大写名
-
static、final等均为修饰符,不区分前后,例如
public class Demo12 { //修饰符 static final double PI = 3.14; //位置不同 public static void main(String[] args) { System.out.println(PI); } }
public class Demo12 { //修饰符 final static double PI = 3.14; //位置不同 public static void main(String[] args) { System.out.println(PI); } }
这两代码均可运行且无错误
变量的命名规范
- 所有变量、方法、类名:见名知意
- 局部变量:首字母小写和驼峰原则
- 常量:全部大写字母,如果过长可加下划线:MAX_VALUE
- 类名:首字母大写和驼峰原则:Man,GoodMan
- 类成员变量:首字母小写和驼峰原则:monthSalary
- 方法名:首字母小写和驼峰原则:run(),runRun()
运算符
- Java语言支持如下运算符
- 算数运算符:+,-,*,/,%,++,–
- 赋值运算符:=
- 关系运算符:>,<,>=,<=,==,!=,instanceof
- 逻辑运算符:&&,||,!
- 位运算符:&,|,^,~,>>,<<,>>>(了解)
- 条件运算符:?,:
- 拓展赋值运算符:+=,-=,*=,/=
多个操作数中,有一个数为long,那么结果就为long;有一个数为double,那么结果就为double;既有long又有double,结果就为double;其他都为int
package Operator; //包
public class Demo01 {
public static void main(String[] args) {
long a = 46546L;
double a1 = 5.12;
int b =123;
short c = 10;
byte d = 8;
System.out.println(a+b+c+d); //long
System.out.println(b+c+d); //int
System.out.println(c+d); //int
System.out.println(a+a1); //double
}
}
自增和自减,又叫一元运算符,需要注意以下运算符的位置,举例,在这个代码中,a原始值为3,a++的意思就是先给b赋值,再自增,这时b等于3,而a=4,再往下,++a的意思就是先自增,再给c赋值,这时a=5,c=5;(代码放的顺序会影响结果,如果把a的输出代码放在a++前面,那么a就等于3)因此a,b,c分别等于5,3,5
自减同理
package Operator;
public class Demo02 {
public static void main(String[] args) {
//++自增 --自减 一元运算符
int a = 3;
int b = a++; //先赋值,再自增
int c = ++a; //先自增,再赋值
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
逻辑与运算:两个变量都为真,结果才为真
逻辑或运算:两个变量有一个为真,则结果才为真
逻辑非运算:如果是真,则为假;如果是假,则为真
package Operator;
public class Demo03 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
System.out.println(a && b);
System.out.println(a || b);
System.out.println(!(a && b));
}
}
这其中,还有一个短路运算,举个例子,看到这段代码,想到的结果肯定是a等于2,b为false,但并非如此,因为与运算是两个变量都为真,结果才为真,而a<0为假,那么结果直接为假,后面的a++<0就不会运算了,此时a还是等于1;这就是短路运算
package Operator;
public class Demo04 {
public static void main(String[] args) {
int a = 1;
boolean b = ((a<0)&&(a++<0));
System.out.println(a);
System.out.println(b);
}
}
位运算直接跟底层打交道,因此效率极高,与逻辑运算一样,不过这个是逐位对比,比较容易出错了,谨慎使用
- &–与运算:两个都为1就返回值1,否则返回值0
- |–或运算:两个有一个1就返回值1,否则返回值0
- ^–异或运算:两个相同就返回值0,否则返回值1
- ~–非运算(或者叫取反):与指定数值相反
举个例子
package Operator;
public class Demo05 {
public static void main(String[] args) {
int a = 0b1011_1100;
int b = 0b1001_0101;
//Integer.toBinaryString 可以让结果以二进制的形式表示
System.out.println(Integer.toBinaryString(a&b));
System.out.println(Integer.toBinaryString(a|b));
System.out.println(Integer.toBinaryString(a^b));
System.out.println(Integer.toBinaryString(~a));
}
}
取反运算只看后面8位就好,前面的请无视,学疏才浅,我也不知道为什么😂,可能跟Integer.toBinaryString有冲突吧;0b开头表示这是个二进制,别忘了
还有一个,左移<<和右移>>,比如有个面试题,2x8如何运算最快?将其拆分为2x2x2x2
- 左移运算<<:表示乘以2
- 右移运算>>:表示除以2
package Operator;
public class Demo06 {
public static void main(String[] args) {
System.out.println(8<<3); //将8乘三次2 8*2*2*2
System.out.println(8>>2); //将8除两次2 8/2/2
}
}
拓展赋值运算符也叫三元运算符,这个很简单,一带而过吧
package Operator;
public class Demo07 {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
a+=b; //a=a+b
c-=b; //c=c-b
System.out.println(a);
System.out.println(c);
}
}
拓展一下字符串连接符+,一般情况下,这是相加的意思,如果加号运算符两侧有一方出现字符串类型,那么结果就是转换成字符然后连接起来
package Operator;
public class Demo07 {
public static void main(String[] args) {
int a = 10;
int b = 20;
//字符串连接符 +
System.out.println(a+b);
System.out.println(""+a+b);
}
}
这里也有另一种情况,有个面试题,System.out.println(""+a+b)和System.out.println(a+b+"")结果分别是多少?这里又是一个代码书写顺序问题了,""表示空字符,写在前面那么就会直接进行字符串连接,如果写在后面,那么a+b依旧会先运算,之后再进行连接
public class Demo07 {
public static void main(String[] args) {
int a = 10;
int b = 20;
//字符串连接符 +
System.out.println(a+b);
System.out.println(""+a+b);
System.out.println(a+b+"");
}
}
条件运算符,这个也简单,但很重要,必须掌握;一个公式就能说清,x ? y:z ;意思就是如果x为真,则结果为y,否则为z;跟if很像
public class Demo08 {
public static void main(String[] args) {
int score = 80;
int score1 = 50;
String type = score<60 ?"不及格":"及格";
String type1 = score1<60 ?"不及格":"及格";
System.out.println(type);
System.out.println(type1);
}
}
运算符优先级
Java 语言中运算符的优先级共分为 14 级,其中 1 级最高,14 级最低。在同一个表达式中运算符优先级高的先执行
优先级 | 运算符 | 结合性 |
---|---|---|
1 | ()、[]、{} | 从左向右 |
2 | !、+(正)、-(负)、~、++、– | 从右向左 |
3 | *、/、% | 从左向右 |
4 | +(加)、-(减) | 从左向右 |
5 | <<、>>、>>> | 从左向右 |
6 | <、<=、>、>=、instanceof | 从左向右 |
7 | ==、!= | 从左向右 |
8 | & | 从左向右 |
9 | ^ | 从左向右 |
10 | | | 从左向右 |
11 | && | 从左向右 |
12 | || | 从左向右 |
13 | ?: | 从右向左 |
14 | =、+=、-=、*=、/=、&=、|=、^=、~=、«=、»=、>>>= | 从右向左 |
这个想记住是很难的,所以要多用括号,这是个好习惯,因为,你总不能这样写代码吧
int a = 5;
int b = 4;
int c = a++- --b*++a/b-- >>2%a--;
太恐怖了好吧!考试可能会出现……
包机制
包机制本质就是文件夹
-
为了更好的组织类,Java提供了包机制,用于区别类名的命名空间
-
包语句的语法格式为:
package pkg1[. pkg2[. pkg3...]];
-
一般利用公司域名倒置作为包名;比如公司域名为www.baidu.com,那么包命名就是com.baidu.www
-
为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包;使用“import”语句可完成此功能,import必须放在package下面
import package1[.package2...].(classname|*);
-
*是通配符,表示所有,比如想把某个包里的所有类都导入进来,但有一万个类,总不能一个一个敲吧,在后面加个星号就行了,比如这样,将com.kongbai.Operator下的类全部导入
import com.kongbai.Operator.*;
JavaDoc
- JavaDoc命令是用来生成自己API文档的
- 参数信息,就是文档注释
- @author 作者名
- @version 版本号
- @since 指明需要最早使用的jdk版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
jdk8帮助文档就是一个官方的JavaDoc [jdk8帮助文档](Overview (Java Platform SE 8 ) (oracle.com));还有中文版的 [jdk8帮助文档中文版](Java 8 中文版 - 在线API中文手册 - 码工具 (matools.com))
package com.kongbai.Base;
/**
* @author Kongbai
* @version 1.0
* @since 1.8
*/ //加在类里面就是类的注释
public class Doc {
String name;
/**
* @author Kongbai
* @param name
* @return
* @throws Exception
*/ //加在方法里就是方法的注释
public String test(String name) throws Exception{
return name;
}
}
在文件夹中打开
老样子,直接在路径前输cmd+空格打开,在cmd中输入javadoc -encoding UTF-8 -charset UTF-8 Doc.java,这两个UTF-8的参数是为了能显示中文
执行一下就是这样了,有警告,但没关系,依旧成功了,此时再返回文件夹,会发现多了很多.html文件,找到index.html打开就是和JavaDoc文档的样子,当然了,啥内容都没有
如何不通过命令而是通过idea生成JavaDoc文档呢?
- 依次点击idea状态栏上Tools->Generate JavaDoc
-
打开后可以看到如下参数
Generate JavaDoc scope:选择你需要生成JavaDoc文档的内容,我这里只需要将Doc这个类生成文档
Output directory:生成的JavaDoc文档存放位置
Locale:选择地区,这个决定文档的语言,zh_CN就是中文
Other command line arguments:
-encoding UTF-8 -charset UTF-8 -author -version -windowtitle "JavaDoc"
注意参数里面的JavaDoc就是你生成的JavaDoc存放的指定目录
-
点击ok就可以生成了,完成会自动打开网页