Java基础语法(No.8)
1、IDEA新建空项目(IDEA New-Built Empty Project)
- 1.1、新建项目。
- 1.2、新建空项目。
- 1.3、自定义项目名称。
- 1.4、新建模块。
- 1.5、新建Java模块。
- 1.6、自定义模块名称。
- 1.7、新建项目结构。
- 1.8、配置项目结构。
- 1.9、新建Java类文件。
- 1.10、输出显示字符串“Hello!World!”。
2、注释(Comments)
一般编写代码,当代码量不多的时候,还比较容易看懂;但当代码量很多或项目结构很复杂的时候,很难一下看懂,这时候就体现出代码注释的好处了。
2.1、行注释(Line Comment)
即,“单行注释”,其语法格式为:"//代码注释内容",注释一行代码(快捷键“Ctrl+/”;且使用“Ctrl+/”, 添加行注释,再次使用,去掉行注释),如下所示。
代码;//单行代码注释
2.2、块注释(Block Comments)
即,“多行注释”,其语法格式为:"/*代码注释内容*/",注释一段连续代码(快捷键“Ctrl+Shift+/”;且使用“Ctrl+Shift+/”, 添加块注释,再次使用,去掉块注释),如下所示。
/* 多行代码注释
代码1;
代码2;
代码3;
*/
2.3、JavaDoc
即,“文档注释”,其语法格式为:"/**文档注释内容*/",注释一段连续文档内容,如下所示。
/** 文档内容注释
* @Description HelloWorld
* @Author 学山学海
*/
2.4、注意事项
- 2.4.1、书写代码注释是一个非常好的习惯。
- 2.4.2、代码注释不会被程序执行,只是方便编写代码的人员查看。
- 2.4.3、书写代码一定要注意规范。
- 2.4.4、很多公司都有这样基本的要求,比如:BAT等。
2.5、有趣的代码注释
“有趣的代码注释"也称为"神代码注释”,通过它也可以培养一下编写代码与注释的乐趣。
3、关键字(Keywords)
Java关键字是电脑语言里事先定义的,有特别意义的标识符,有时又叫保留字,还有特别意义的变量。Java的关键字对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名、方法名、类名、包名和参数,如下图所示。
4、标识符(Identifier)
Java所有的组成部分都需要名字。类名、变量名、方法名都被称为标识符。
-
1、标识符由字母、数字、下划线“_”、汉字、美元符号“$”组成,且第一个字符不能是数字。
-
2、不能把Java关键字和保留字作为标识符。
-
3、标识符没有长度限制。
-
4、标识符对大小写敏感。
-
5、可以使用中文命名,但一般不建议使用,也不建议使用拼音字母命名(Low)。
5、数据类型(Data Type)
5.1、强类型语言(Strong Type Language)
强类型语言也称为强类型定义语言。是一种总是强制类型定义的语言,要求变量的使用要严格符合定义,所有变量都必须先定义后使用。比如:Java、C#、C、C++语言等。
5.2、弱类型语言(Weak Type Language)
弱类型语言也称为弱类型定义语言。与强类型定义相反。比如:VB、PHP语言等。
5.3、Java数据类型(Java Data Type)
-
5.3.1、基本类型(Primitive Type)
-
5.3.1.1、数值类型
-
5.3.1.1.1、整数类型
-
5.3.1.1.1.1、byte
占1个字节(Byte),即8个位[比特,bit],且每个位代表一个“0”或“1”的二进制数字(Binary Digits),取值范围“-27~27-1(即,-128~127)”。
-
5.3.1.1.1.1、short
占2个字节(Byte),即16个位[比特,bit],且每个位代表一个“0”或“1”的二进制数字(Binary Digits),取值范围“-215~215-1(即,-32768~32767)”。
-
5.3.1.1.1.1、int
占4个字节(Byte),即32个位[比特,bit],且每个位代表一个“0”或“1”的二进制数字(Binary Digits),取值范围“-231~231-1(即,-2147483648~2147483647)”。
-
5.3.1.1.1.1、long
占8个字节(Byte),即64个位[比特,bit],且每个位代表一个“0”或“1”的二进制数字(Binary Digits),取值范围“-263~263-1(即,-9223372036854775808~9223372036854775807)”。
-
-
5.3.1.1.2、浮点类型
float和double的范围是由指数的位数来决定的,并且指数位是按补码的形式来划分的。其中负指数决定了浮点数所能表达的绝对值最小的非零数;而正指数决定了浮点数所能表达的绝对值最大的数,也即决定了浮点数的取值范围。
float和double的精度是由尾数的位数来决定的,浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。
-
5.3.1.1.2.1、float
占4个字节(Byte),其存储方式为“1bit(符号位)8bits(指数位)23bits(尾数位)”。
-
5.3.1.1.2.1.1、范围
float的指数范围为-128~+127,float的范围为-2^128 ~ +2^127,也即-3.40E+38 ~ +1.70E+38。
-
5.3.1.1.2.1.2、精度
2^23 = 8388608,一共七位,由于最左为1的一位省略了,这意味着最多能表示8位数: 2*8388608=16777216 。有8位有效数字,但绝对能保证的为7位,也即 float的精度为7~8位有效数字。
-
-
5.3.1.1.2.2、double
占8个字节(Byte),其存储方式为“1bit(符号位)11bits(指数位)52bits(尾数位)”。
-
5.3.1.1.2.2.1、范围
double的指数范围为-1024~+1023,double的范围为-2^1024 ~ +2^1023,也即-1.79E+308 ~ +0.89E+308。
-
5.3.1.1.2.2.2、精度
2^52 = 4503599627370496,一共16位,由于最左为1的一位省略了,这意味着最多能表示17位数: 2*4503599627370496=9007199254741000 。有17位有效数字,但绝对能保证的为16位,也即double的精度为16~17位。
-
-
-
5.3.1.1.3、字符类型
占2个字节(Byte)。
-
-
5.3.1.2、布尔类型
占1个位[比特,bit],且该位代表一个“0”或“1”的二进制数字(Binary Digits),其对应取值只能为“False”或“True”。
-
-
5.3.2、引用类型(Reference Type)
引用类型由类型的实际值引用(类似于指针)表示的数据类型。如果为某个变量分配一个引用类型,则该变量将引用(或“指向”)原始值。不创建任何副本。
- 5.3.2.1、类
- 5.3.2.2、接口
- 5.3.2.3、数组
6、数据类型扩展及面试题讲解
6.1、整数扩展(Integer [Number] Extension)
整数常用进制包括二进制(使用"0b"开头显示)、八进制(使用"0"开头显示)、十进制(系统默认整数进制类型)、十六进制(使用"0x"开头显示),其使用方法如以下代码块所示。
//======================================================================
//整数扩展(进制) 二进制(0b)、八进制(0)、十进制、十六进制(0x)
//======================================================================
int i2=0b10;//二进制
int i8=010;//八进制
int i10=10;//十进制
int i16=0x10;//十六进制
System.out.println("二进制(0b10)对应的十进制("+i2+")");
System.out.println("八进制(010)对应的十进制("+i8+")");
System.out.println("十进制("+i10+")");
System.out.println("十六进制(0x10)对应的十进制("+i16+")");
System.out.println("=================================================");
其运行结果,如下图所示。
6.2、浮点数扩展(Float Number Extension)
浮点数包括单精度浮点数(float,一般用“f”或“F”表示)、双精度浮点数(double,一般用“d”或“D”表示,且为系统默认浮点数类型),其使用方法如以下代码块所示。
//======================================================================
//浮点数扩展 比如“银行业务中钱如何计算”???
//最好避免使用浮点数进行比较计算(后续使用BigDecimal<数学工具类>实现)
//======================================================================
//浮点数特点:有限、离散、舍入误差、大约、接近但不等于
//float(7~8位有效数字,绝对保证的是7位)
//double(16~17位有效数字,绝对保证的是16位)
float f=0.1f;//0.1
double d=1.0d/10D;//0.1
System.out.println(f==d);//判定变量f是否等于变量d,若相等则返回true,否则返回False
//float f1=23131312312312313f;
float f1=16777216F;
float f2=f1+1;
System.out.println(f1+"---"+f2);
System.out.println(f1==f2);//判定变量f1是否等于变量f2,若相等则返回true,否则返回False
System.out.println("=================================================");
其运行结果,如下图所示。
6.3、字符扩展(Character Extension)
其使用方法如以下代码块所示。
//======================================================================
//字符扩展 所有的字符本质上还是数字
//字符编码(Unicode编码) 2个字节(取值范围0~2^16-1(65535),即U0000~UFFFF)
//比如Excel2003的最大行数(2^16=65536)、最大列数(2^8=256)
//比如Excel2007开始的版本最大行数(2^20=1048576)、最大列数(2^14=16384)
//======================================================================
char c1='a';
char c2='汉';
System.out.println(c1);
System.out.println((int)c1);//强制转换
System.out.println(c2);
System.out.println((int)c2);//强制转换
//转义字符"\" "\t"代表制表符 “\n”代表“换行” "\r"代表"回车"
System.out.println("Hello\tWorld");
System.out.println("Hello\r\nWorld");
System.out.println("\u0061");//16进制数"0061"的Unicode编码对应字符“a”
//对象(后续从内存分析)
String s1=new String("Hello!World!");
String s2=new String("Hello!World!");
System.out.println(s1==s2);//false
String s3="Hello!World!";
String s4="Hello!World!";
System.out.println(s3==s4);//true
System.out.println("=================================================");
其运行结果,如下图所示。
6.4、布尔值扩展(Boolean [Value] Extension)
其使用方法如以下代码块所示。
//======================================================================
//布尔值扩展 (less is more,少即是多,亦即“代码要精简易读”)
//======================================================================
boolean bool=true;
if(bool==true){System.out.println("新手写的代码");}//新手
if(bool){System.out.println("老手写的代码");}//老手
System.out.println("=================================================");
其运行结果,如下图所示。
7、类型转换(Type Conversion)
由于Java是强类型语言,需用到类型转换进行某些运算。在运算时,不同类型的数据要先转换成同一类型,然后进行运算。
7.1、类型转换优先级(Type Conversion Priority)
从低到高,分别依次为“byte,short,char->int->long->float->double”。
7.2、强制类型转换(Force Type Conversion)
其语法为“(类型)变量名”,且当从优先级高的类型往优先级低的类型转换时才需使用,如以下代码所示。
//强制类型转换
int i1=128;
byte b=(byte)i1;//内存溢出
int i11=(int)12.345;//丢失精度
int i12=(int)-12.345;//丢失精度
System.out.println(i1);
System.out.println(b);
System.out.println(i11);
System.out.println(i12);
System.out.println("=================================================");
其运行结果,如下图所示。
7.3、自动类型转换(Automatic Type Conversion)
无需任何操作,且当从优先级低的类型往优先级高的类型转换时自动进行,如以下代码所示。
//自动类型转换
int i2=256;
long l=i2;
char c='a';
int i3=c+1;
System.out.println(i2);
System.out.println(l);
System.out.println(c);
System.out.println(i3);
System.out.println("=================================================");
其运行结果,如下图所示。
7.4、注意事项(Matters Needing Attention)
- 7.4.1、不能对布尔值进行转换
- 7.4.2、不能把对象类型转换成不相干的类型
- 7.4.3、在高容量类型转换为低容量类型时,需强制类型转换
- 7.4.4、类型转换时可能会存在内存溢出或精度问题
7.5、特殊异常(Special Anomaly)
操作比较大的数据时,注意溢出问题,如以下代码所示。
//特殊异常
//操作比较大的数据时,注意溢出问题。
//JDK7新特性:数字之间可以用下划线“_”分割显示
int money=10_0000_0000;
int year=20;
int total1=money*year;//内存溢出
long total2=money*year;//默认是int类型,转换之前就内存溢出
long total3=money*((long)year);//先把一个数字转换为long
System.out.println(total1);
System.out.println(total2);
System.out.println(total3);
System.out.println("=================================================");
其运行结果,如下图所示。
8、变量(Variable)、常量(Constant)、命名规范(Naming Convention)
8.1、变量(Variable)
变量就是可以变化的量。Java是一种强类型语言,每个变量都必须声明其类型。Java变量是程序中最基本的存储单元,其要素包括“变量类型(Variable Type)、变量名(Variable Name)、作用域(Action Scope)”。
- 8.1.1、语法格式(Grammatical Format)
其语法格式为“type varName [=value] [{,varName[=value]}];”,可以使用逗号隔开来声明多个同类型变量(不推荐使用)。
-
8.1.2、作用域(Action Scope)
-
8.1.2.1、类变量(Class Variable)
在类中方法外声明,并使用关键字“static”来修饰,可在类中任意使用。
-
8.1.2.2、实例变量(Instance Variable)
在类中方法外声明,只能在实例化类对象后方可使用。
-
8.1.2.3、局部变量(Local Variable)
在类中方法里声明,只能在方法里使用。
-
-
8.1.3、使用方法(Usage Method)
其使用方法如以下代码所示。
public class Variable { //属性:变量 //类变量:使用关键字“static”修饰 static double salary=5000; //实例变量:从属于类的对象,必须声明,但可以不初始化,若未初始化,则为该类型默认值 //基本类型中,“byte、short、int、long”默认值为0,“float、double”默认值为0.0,“char”默认值为U0000,“boolean”默认值为false //除基本类型以外的所有引用类型默认值为null byte be;//基本类型 short st;//基本类型 int it;//基本类型 long lg;//基本类型 float ft;//基本类型 double de;//基本类型 char cr;//基本类型 boolean bn;//基本类型 String sg;//引用类型 //main方法 public static void main(String[] args) { //局部变量:必须声明与初始化 //int a=1,b=2,c=3;//不推荐使用(程序可读性太差) byte by=1;//基本类型 short sh=2;//基本类型 int in=3;//基本类型 long lo=4;//基本类型 float fl=5;//基本类型 double db=6;//基本类型 char ch=7;//基本类型 boolean bo=true;//基本类型 String st="hello";//引用类型 System.out.println("byte类型局部变量("+by+")short类型局部变量("+sh+")int类型局部变量("+in+")\r\nlong类型局部变量("+lo+")float类型局部变量("+fl+")double类型局部变量("+db+")\r\nchar类型局部变量("+ch+")boolean类型局部变量("+bo+")String类型局部变量("+st+")"); Variable var=new Variable();//实例化类的对象 System.out.println("byte类型实例变量("+var.be+")short类型实例变量("+var.st+")int类型实例变量("+var.it+")\r\nlong类型实例变量("+var.lg+")float类型实例变量("+var.ft+")double类型实例变量("+var.de+")\r\nchar类型实例变量("+var.cr+")boolean类型实例变量("+var.bn+")String类型实例变量("+var.sg+")");//实例变量 System.out.println("double类型类变量("+salary+")");//类变量 var.Test();//调用其他方法 } //其他方法 public void Test(){ System.out.println("调用其他方法"); Variable vt=new Variable();//实例化类的对象 System.out.println("byte类型实例变量("+vt.be+")short类型实例变量("+vt.st+")int类型实例变量("+vt.it+")\r\nlong类型实例变量("+vt.lg+")float类型实例变量("+vt.ft+")double类型实例变量("+vt.de+")\r\nchar类型实例变量("+vt.cr+")boolean类型实例变量("+vt.bn+")String类型实例变量("+vt.sg+")");//实例变量 System.out.println("double类型类变量("+salary+")");//类变量 } }
-
8.1.4、运行结果(Running Results)
其运行结果如下图所示。
-
8.1.5、注意事项(Matters Needing Attention)
- 8.1.5.1、每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 8.1.5.2、变量名必须是合法的标识符。
- 8.1.5.3、变量声明是一条完整的语句,因此每一个声明都必须以分号结束。
8.2、常量(Constant)
常量初始化(Initialization)后不能再改变值,即不能变化的量。所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变。
-
8.2.1、语法格式(Grammatical Format)
其语法格式为“final type constName=value [{,constName=value}];”,可以使用逗号隔开来声明多个同类型变量(不推荐使用)。
-
8.2.2、作用域(Action Scope)
在类中方法外声明,并使用关键字“static”来修饰,可在类中任意使用。
-
8.2.3、使用方法(Usage Method)
其使用方法如以下代码所示。
public class Constant { //常量 //static final double PI=3.1415926535898,GOLDEN_SECTION_NUMBER=0.618;//不推荐使用(程序可读性太差) //修饰符:不存在先后顺序 //final static double PI=3.1415926535898;//写法一 //final static double GOLDEN_SECTION_NUMBER=0.618;//写法一 static final double PI=3.1415926535898;//写法二 static final double GOLDEN_SECTION_NUMBER=0.618;//写法二 public static void main(String[] args) { System.out.println("常量圆周率("+PI+")常量黄金分割比("+GOLDEN_SECTION_NUMBER+")"); } }
-
8.2.4、运行结果(Running Results)
其运行结果如下图所示。
-
8.2.5、注意事项(Matters Needing Attention)
- 常量名一般使用大写字符。
- 用作修饰符的关键字不存在先后顺序。
8.3、命名规范(Naming Convention)
- 8.3.1、所有变量、方法、类名:见名知意,如“monthSalary”代表“月薪变量”、“main()”代表“主函数(即程序执行起点)”、“NamingConvention”代表“命名规范类”。
- 8.3.2、类成员变量:首字母小写和驼峰原则,即除了第一个单词以外,后面的单词首字母大写,如“monthSalary”。
- 8.3.3、局部变量:首字母小写和驼峰原则,如“lastDay”。
- 8.3.4、常量:大写字母和下划线,如“PI、GOLDEN_SECTION_NUMBER”。
- 8.3.5、方法名:首字母小写和驼峰原则,如“main()、runMachine()”。
- 8.3.6、类名:首字母大写和驼峰原则,如“NamingConvention、HelloWorld”。
9、基本运算符(Basic Operators)
9.1、算术运算符(Arithmetical Operator)
其包含符号“+(加)、-(减)、*(乘)、/(除)、%(取余或取模)、++(自增)、–(自减)”,如以下代码所示。
package Operator;
public class ArithmeticalOperator {
public static void main(String[] args) {
//算术运算符
//快捷键“Ctrl+D”作用:复制当前行到下一行
int a=10;
int b=20;
int c=a++;//执行完这行代码后,先给c赋值,再自增a
int d=a--;//执行完这行代码后,先给d赋值,再自减a
int e=++a;//执行完这行代码前,先自增a,再给e赋值
int f=--a;//执行完这行代码前,先自减a,再给f赋值
System.out.println("a+b="+(a+b)+",a-b="+(a-b)+",a*b="+(a*b)+",a/b="+(a/(double)b)+"\r\n,a%b="+(a%b)+",(a++)="+(c)+",(a--)="+(d)+",(++a)="+(e)+",(--a)="+(f));
//特别注意:算术运算符的操作数类型大于Int类型时,运算结果类型为其中最大类型,否则运算结果类型全部为Int类型
byte b1=1;
short s1=2;
int i1=3;
long l1=1234567890123456789L;//long类型小写简写"l"或大写"L",一般推荐使用大写简写"L"
float f1=5;
double d1=6.0;
char c1='a';
System.out.println(b1+s1+i1+l1+f1+d1+c1);//运算结果类型为double
System.out.println(b1+s1+i1+l1+f1+c1);//运算结果类型为float
System.out.println(b1+s1+i1+l1+c1);//运算结果类型为long
System.out.println(b1+s1+i1+c1);//运算结果类型为int
}
}
其运行结果,如下图所示。
- 特别注意:算术操作符的操作数类型大于Int类型时,运算结果类型为其中最大类型,否则运算结果类型全部为Int类型。
9.2、赋值运算符(Assignment Operator)
其包含符号“=(赋值)”。
9.3、关系运算符(Relational Operator)
其包含符号“>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、==(等于)、!=(不等于)、instanceof(实例,其作用是判断其左边对象是否为其右边类的实例,类似c#中is操作符)”,其返回结果类型为Boolean类型,如以下代码所示。
package Operator;
public class RelationalOperator {
public static void main(String[] args) {
//关系运算符:返回结果类型为Boolean类型
int a=1;
int b=2;
RelationalOperator rO=new RelationalOperator();
System.out.println("(a>b)="+(a>b)+",(a<b)="+(a<b)+",(a>=b)="+(a>=b)+"\r\n,(a<=b)="+(a<=b)+",(a==b)="+(a==b)+",(a!=b)="+(a!=b)+"\r\n,(rO instanceof RelationalOperator)="+(rO instanceof RelationalOperator));
}
}
其运行结果,如下图所示。
9.4、逻辑运算符(Logical Operator)
其包含符号“&&(与)、||(或)、!(非,取反)”,其返回结果类型为Boolean类型,如以下代码所示。
package Operator;
public class LogicalOperator {
public static void main(String[] args) {
//逻辑运算符
boolean b1=true;
boolean b2=false;
System.out.println("(b1&&b2)="+(b1&&b2));//逻辑与运算:两个变量都为true,结果才为true。
System.out.println("(b1||b2)="+(b1||b2));//逻辑或运算:两个变量有一个为true,结果就为true。
System.out.println("!(b1&&b2)="+!(b1&&b2));//逻辑非(取反)运算:如果为true,结果为false;如果为false,结果为true。
//短路运算:若运算符左边结果已满足最后运算结果,则无需再运算右边结果。
int i=3;
boolean b=(i<3)&&(i++>5);
System.out.println("b="+b+",i="+i);
}
}
其运行结果,如下图所示。
- 特别注意:短路运算,即,若运算符左边结果已满足最后运算结果,则无需再运算右边结果。
9.5、位运算符(Positional Operator)
其包含符号“&(按位与)、|(按位或)、^(按位异或)、~(按位取反)、>>(按位右移,如果该数为正,则高位补0,若为负数,则高位补1)、<<(按位左移,不分正负数,低位补0)、>>>(按位无符号右移,即,逻辑右移,若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0)”(了解一下即可),如以下代码所示。
package Operator;
public class PositionalOperator {
public static void main(String[] args) {
//位运算符
/*
//以下数据默认为int类型32位
//正数的原码、反码、补码相同
//A的值为十进制60
原码:00000000 00000000 00000000 00111100
反码:00000000 00000000 00000000 00111100
补码:00000000 00000000 00000000 00111100
//负数的原码:负数的反码符号位不变其余按位取反
//负数的反码:负数的原码符号位不变其余按位取反
//负数的补码:负数的原码符号位不变其余按位取反后+1,即“负数的反码+1”
//B的值为十进制-28
原码:10000000 00000000 00000000 00011100
反码:11111111 11111111 11111111 11100011
补码:11111111 11111111 11111111 11100100
---------------------------------------------
//按位与(&):按补码形式参加运算,若对应位都是1,则为1,否则都为0。
A&B=(00000000 00000000 00000000 00111100)&(11111111 11111111 11111111 11100100)=
00000000 00000000 00000000 00100100(补码)=
00000000 00000000 00000000 00100100(反码)=
00000000 00000000 00000000 00100100(原码)=36(十进制)
//按位或(|):按补码形式参加运算,若对应位都是0,则为0,否则都为1。
A|B=(00000000 00000000 00000000 00111100)&(11111111 11111111 11111111 11100100)=
11111111 11111111 11111111 11111100(补码)=
11111111 11111111 11111111 11111011(反码=补码-1)=
10000000 00000000 00000000 00000100(原码=反码符号位不变其余按位取反)=-4(十进制)
//按位异或(^):按补码形式参加运算,若对应位都相同,则为0,否则都为1。
A^B=(00000000 00000000 00000000 00111100)&(11111111 11111111 11111111 11100100)=
11111111 11111111 11111111 11011000(补码)=
11111111 11111111 11111111 11010111(反码=补码-1)=
10000000 00000000 00000000 00101000(原码=反码符号位不变其余按位取反)=-40(十进制)
//按位取反(~):按补码形式参加运算,若对应位为1,则为0,对应位为0,则为1。
//特别注意:所有位都要按位取反(包含符号位),且按位取反等价于公式“-(x+1),其中x为计算数”。
~A=~(00000000 00000000 00000000 00111100)=11111111 11111111 11111111 11000011(补码)=
11111111 11111111 11111111 11000010(反码=补码-1)=
10000000 00000000 00000000 00111101(原码=反码符号位不变其余按位取反)=-61(十进制)
~B=~(11111111 11111111 11111111 11100100)=00000000 00000000 00000000 00011011(补码)=
00000000 00000000 00000000 00011011(反码)=00000000 00000000 00000000 00011011(原码)=27(十进制)
---------------------------------------------
//按位左移(<<):按补码形式参加运算,实质上左移n位就是“*2^n(乘以2的n次方)”,符号位不变,不分正负数,低位补0。
A<<2=(00000000 00000000 00000000 00111100)<<2=00000000 00000000 00000000 11110000(补码)=
00000000 00000000 00000000 11110000(反码)=00000000 00000000 00000000 11110000(原码)=240(十进制)
B<<2=(11111111 11111111 11111111 11100100)<<2=11111111 11111111 11111111 10010000(补码)=
11111111 11111111 11111111 10001111(反码=补码-1)=
10000000 00000000 00000000 01110000(原码=反码符号位不变其余按位取反)=-112(十进制)
//十进制-27
原码:10000000 00000000 00000000 00011011
反码:11111111 11111111 11111111 11100100
补码:11111111 11111111 11111111 11100101
-27<<2=(11111111 11111111 11111111 11100101)<<2=11111111 11111111 11111111 10010100(补码)=
11111111 11111111 11111111 10010011(反码=补码-1)=
10000000 00000000 00000000 01101100(原码=反码符号位不变其余按位取反)=-108(十进制)
//按位右移(>>):按补码形式参加运算,实质上右移n位就是“/2^n(除以2的n次方)”,符号位不变,若为正数,则高位补0,若为负数,则高位补1。
A>>2=(00000000 00000000 00000000 00111100)>>2=00000000 00000000 00000000 00001111(补码)=
00000000 00000000 00000000 00001111(反码)=00000000 00000000 00000000 00001111(原码)=15(十进制)
B>>2=(11111111 11111111 11111111 11100100)>>2=11111111 11111111 11111111 11111001(补码)=
11111111 11111111 11111111 11111000(反码=补码-1)=
10000000 00000000 00000000 00000111(原码=反码符号位不变其余按位取反)=-7(十进制)
//十进制-27
原码:10000000 00000000 00000000 00011011
反码:11111111 11111111 11111111 11100100
补码:11111111 11111111 11111111 11100101
-27>>2=(11111111 11111111 11111111 11100101)>>2=11111111 11111111 11111111 11111001(补码)=
11111111 11111111 11111111 11111000(反码=补码-1)=
10000000 00000000 00000000 00000111(原码=反码符号位不变其余按位取反)=-7(十进制)
//按位无符号右移(>>>):即,逻辑右移,按补码形式参加运算,若为正数,则高位补0,若为负数,则右移后高位同样补0。
A>>>2=(00000000 00000000 00000000 00111100)>>>2=00000000 00000000 00000000 00001111(补码)=
00000000 00000000 00000000 00001111(反码)=00000000 00000000 00000000 00001111(原码)=15(十进制)
B>>>2=(11111111 11111111 11111111 11100100)>>>2=00111111 11111111 11111111 11111001(补码)=
00111111 11111111 11111111 11111001(反码)=00111111 11111111 11111111 11111001(原码)=1073741817(十进制)
//十进制-27
原码:10000000 00000000 00000000 00011011
反码:11111111 11111111 11111111 11100100
补码:11111111 11111111 11111111 11100101
-27>>>2=(11111111 11111111 11111111 11100101)>>>2=00111111 11111111 11111111 11111001(补码)=
00111111 11111111 11111111 11111001(反码)=00111111 11111111 11111111 11111001(原码)=1073741817(十进制)
*/
int A=60;
int B=-28;
System.out.println("A="+A+",B="+B);
System.out.println("=================================================");
System.out.println("按位与运算:(A&B)="+(A&B));
System.out.println("按位或运算:(A|B)="+(A|B));
System.out.println("按位异或运算:(A^B)="+(A^B));
System.out.println("按位取反运算:(~A)="+(~A)+",(~B)="+(~B));
System.out.println("=================================================");
int C=-27;
System.out.println("C="+C);
System.out.println("=================================================");
System.out.println("按位左移运算:(A<<2)="+(A<<2)+",(B<<2)="+(B<<2)+",(C<<2)="+(C<<2));
System.out.println("按位右移运算:(A>>2)="+(A>>2)+",(B>>2)="+(B>>2)+",(C>>2)="+(C>>2));
System.out.println("按位无符号右移(即,逻辑右移)运算:(A>>>2)="+(A>>>2)+",(B>>>2)="+(B>>>2)+",(C>>>2)="+(C>>>2));
System.out.println("=================================================");
//特别注意:面试题“2*8(即,2*2*2*2)=16如何运算最快???”。
//原理解析:16=2*2*2*2相当于十进制数2对应的二进制数往左移动了3位
System.out.println("2*8使用按位左移运算(2<<3)="+(2<<3));//十进制数2左移3位,结果为十进制数16
}
}
其运行结果,如下图所示。
- 特别注意
- 使用位运算的效率极高。
- 所有位运算都要按二进制补码形式参加运算。
- 正数的原码、反码、补码相同。
- 负数的原码:负数的反码符号位不变其余按位取反。
- 负数的反码:负数的原码符号位不变其余按位取反,即“负数的补码-1”。
- 负数的补码:负数的原码符号位不变其余按位取反后+1,即“负数的反码+1”。
- 按位与(&):若对应位都是1,则为1,否则都为0。
- 按位或(|):若对应位都是0,则为0,否则都为1。
- 按位异或(^):若对应位都相同,则为0,否则都为1。
- 按位取反(~):若对应位为1,则为0,对应位为0,则为1,其中所有位都要按位取反(包含符号位),且按位取反等价于公式“-(x+1),其中x为计算数”。
- *按位左移(<<):实质上左移n位就是“2^n(乘以2的n次方)”,符号位不变,不分正负数,低位补0。
- 按位右移(>>):实质上右移n位就是“/2^n(除以2的n次方)”,符号位不变,若为正数,则高位补0,若为负数,则高位补1。
- 按位无符号右移(>>>):即,逻辑右移,若为正数,则高位补0,若为负数,则右移后高位同样补0。
9.6、条件运算符(Conditional Operator)
其包含符号“?:”,如以下代码所示。
package Operator;
public class ConditionalOperator {
public static void main(String[] args) {
//条件运算符:x?y:z,即,若x等于true,则结果为y,否则结果为z
int score=90;
String grade=score>=60?"及格":"不及格";//必须掌握
System.out.println("grade="+grade);
}
}
其运行结果,如下图所示。
-
特别注意
关于运算符的优先级,推荐使用"()",可以让代码通俗易懂,也不容易因为优先级出错。
9.7、扩展赋值运算符(Extended Assignment Operator)
其包含符号“+=、-=、*=、/=”,如以下代码所示。
package Operator;
public class ExtendedAssignmentOperator {
public static void main(String[] args) {
int a=10;
int b=20;
System.out.println("a="+a+",b="+b);
System.out.println("a+=b的值为:"+(a+=b));//a+=b等价于a=a+b
System.out.println("a-=b的值为:"+(a-=b));//a-=b等价于a=a-b
System.out.println("a*=b的值为:"+(a*=b));//a*=b等价于a=a*b
System.out.println("a/=b的值为:"+(a/=b));//a/=b等价于a=a/b
//扩充:字符串连接符“+”,只要其中“+”一边操作数出现字符串,就会把其他操作数都转换成字符串来连接。
System.out.println(""+a+b);//结果为“1020”,所有字符串连接符“+”的两边数据都当成字符串连接处理
System.out.println(a+b+"");//结果为“30”,第一个字符串变量前面的数据正常运算后,再与字符串连接处理
}
}
其运行结果,如下图所示。
10、初识Math类
Java中有很多运算,都需要使用一些工具类来操作,比如“Math类”,如以下代码所示。
package Operator;
public class MathClass {
public static void main(String[] args) {
//幂运算扩展:比如2^3=2*2*2=8,我们要使用工具类(Math)来操作
double power=Math.pow(2,3);//使用工具类(Math)来操作幂运算
System.out.println("2^3="+power);
}
}
其运行结果,如下图所示。
11、包机制
为了更好的组织类,Java提供了包机制,用于区别类名的命名空间。
11.1、包的定义
其语法格式为:“package pkg1[.pkg2[.pkg3…];”,一般利用公司域名倒置作为包名(比如:"www.baidu.com"的包名一般为“com.baidu.www”)。
11.2、包的导入
为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包,使用"import"语句可完成此功能,其语法格式为:“import package1[.package2…].(classname|*);”,如:“”。
11.3、包的用法
如以下代码所示。
package com.xueshanxuehai.Operator;//定义包"com.xueshanxuehai.Operator"
//import com.xueshanxuehai.Basic.Variable;//导入包“com.xueshanxuehai.Basic”中的类"Variable"
import com.xueshanxuehai.Basic.*;//"*"通配符,代表导入指定包“com.xueshanxuehai.Basic”中的所有类
public class ConditionalOperator {
public static void main(String[] args) {
//条件运算符:x?y:z,即,若x等于true,则结果为y,否则结果为z
int score=90;
String grade=score>=60?"及格":"不及格";//必须掌握
System.out.println("grade="+grade);
Variable.Test();//调用包“com.xueshanxuehai.Basic.Variable”中的Test方法
}
}
其运行结果,如下图所示。
- 特别注意
- 包的本质就是文件夹。
- 包的名称尽量不要重复。
- 推荐抽时间看一下《阿里巴巴Java开发手册》。
12、JavaDoc生成文档
Javadoc是Sun公司提供的一个技术,它从程序源代码中抽取类、方法、成员等注释形成一个和源代码配套的API帮助文档。也就是说,只要在编写程序时以一套特定的标签作注释,在程序编写完成后,通过Javadoc就可以同时形成程序的开发文档了。
12.1、参数信息
- 1、@author 作者名。
- 2、@version 版本号。
- 3、@since 指明需要最早使用的JDK版本。
- 4、@param 参数名。
- 5、@return 返回值情况。
- 6、@throws 异常抛出情况。
12.2、文档注释
如以下代码所示。
package com.xueshanxuehai.Basic;//包
/**类文档注释
* @author 学山学海
* @version 1.0
* @since 1.8
*/
public class JavaDoc {//类
String name;//属性
/**方法文档注释
* @author 学山学海
* @param name
* @return
* @throws Exception
*/
public String getName(String name) throws Exception{//方法
return name;
}
}
12.3、JavaDoc命令生成文档
Javadoc命令是用来生成自己API文档的,使用方法:使用命令行在目标文件所在目录输入“javadoc ”+“参数值”+“ 文件名.java”,如下图所示。
-
12.3.1、打开生成JavaDoc文档的本地Java文件。
-
12.3.2、打开当前Java文件路径对应的cmd命令窗口。
-
12.3.3、执行生成指定Java文件文档的cmd命令。
-
12.3.4、查看已生成JavaDoc文档相关文件。
-
12.3.5、查看JavaDoc文档中首页文件"index.html"。
12.4、IDEA生成文档
-
12.4.1、单击IDEA中菜单"Tools"的子菜单"Generate JavaDoc…"选项。
-
12.4.2、IDEA生成文档配置参数。
-
12.4.3、查看IDEA已生成JavaDoc文档相关文件。
-
12.4.4、查看IDEA已生成JavaDoc文档中首页文件"index.html"。