导图社区 JAVA编程语言-导图
JAVA编程语言基础语法知识总结,包括JAVA语言的特点、JAVA开发环境、数据类型、类和对象、输入输出等等。
编辑于2022-08-10 11:36:51 上海JAVA
基础知识
JAVA语言的特点
面向对象
安全性
删除了指针和释放内存,避免非法内存操作
Java安全体系架构
平台无关性
JVM支持
支持多线程
内置多线程
内存管理
内存回收技术
要被回收的无用对象的定义: 1.当前代码段不属于对象的作用域 2.把对象的引用赋为空 即:对象变得不可达到
垃圾收集器(gc:garbage collector)
作为JVM的一个后台线程运行 在系统空闲时异步执行 当系统内存用尽时执行 调用System.gc()时执行 自动扫描对象的动态内存区, 对需要回收的对象标记并回收
finalize()方法
Object中有声明,类比C++析构函数 //需要释放出内存以外的资源需要重写finalize方法 //建议避免主动使用 protected void finalize() throws throwable{ }
JAVA开发环境
JDK 开发工具
基础类库(API)
即JAVA中自带的包 
JAVA编译器javac.exe
JAVA解释器java.exe
bin目录下
JRE 运行环境
配置环境变量时的CLASSPATH,文件在lib中
JVM(JAVA虚拟机)
用于实现跨平台性
JAVA核心类库
通常一起安装
JAVA程序的编译过程
1.编写.java文件 2.由java编译器javac.exe进行编译(Compiler),生成.class文件(一种可以让JVM识别的指令,字节码文件) 3.由java解释器java.exe进行解释(Interpreter)、交由JVM运行程序
不同类型的JAVA平台
JAVA SE
Standard Edition(基础版)
JAVA ME
Micro Edition(用于手持设备和嵌入式设备的开发)
JAVA EE
Enterprise Edition(分布式开发,面向Web的企业级应用)
数据类型
基本数据类型
*值传递 *不初始化的基本数据类型 若是类的成员,会有缺省值 若是局部变量,不会有缺省值 缺省值表: 
数值型
整型默认 int 浮点型默认 double
整数类型(byte/short/int/long)
浮点类型(float/double)
字符型(char)
布尔型(boolean)
对应的有封装类对象,可自动装箱拆箱
引用数据类型
引用传递
数组
一维数组: type [] arrayName = new type[x]; 二维数组,每个数组可以不等长: type [][] arrayName = new type[x][y]; x可以为变量 系统会默认初始化
类
接口
内存划分
栈内存
储存基本数据类型和对象的引用变量
堆中的对象或数组的首地址赋给了栈中的引用变量
堆内存
储存new出来的对象实体
表达式与运算符
基本与C/C++类似
类型比较运算符:e instanceof Point
编译器会检查 待判断变量 是否能转换成右边的类型, 如果不能转换则直接报错, 如果不能确定类型,则通过编译,具体看运行时定
类型转换
Java类型转换包括: 自动类型转换(子集到超集,以占位多少为依据:如int->double,数值型) 显式类型转换(反之) 所以Java是强类型语言 而弱类型语言则是无论什么变量都可以相互转换
赋值转换
方法调用转换
强制转换
字符串转换
toString()函数显式转换
类和对象
类是对 对象的抽象
面向对象思想
抽象
数据抽象
属性
过程抽象
方法
封装
隐蔽信息 降低耦合度 易于程序的维护与修改
访问控制符
接口
受保护的内部实现
继承
提高代码的可重用性 默认继承(由JVM实现):Object是所有类的祖先类
Java仅支持类的单继承
多态
同名的不同方法
方法重载 overload
一个类中有两个及以上同名的方法,但参数表不同 这些方法的签名(signature)不同
类的声明和使用
类的声明
[public] [abstract| final] class 类名称 [extends 父类名称] [implements 接口名称列表] { 变量成员声明及初始化; 方法声明及方法体; } *类的访问权限只有public和无修饰符两种 *一个.java文件只能有一个public类/公开接口(可以没有),且类名与文件名一致
数据成员
可以是Java中任意的数据类型 格式 [ public | protected | private ] [ static ][ final ][ transient ] [ volatile ] 变量数据类型 变量名1[=变量初值] , 变量名2[=变量初值], … ; *数据成员可以有自定义默认值 *static: 静态(不能修饰局部变量) *final: 终结 *transient: 瞬态 *voatile: 共享 *未定义访问权限时为default
实例变量
类变量(静态变量)
static修饰 可以用类名或对象名调用 类的所有对象共享一份 可以通过类名或者实例对象访问
方法成员
[ public | protected | private ] [static][final|abstract] [native] [synchronized] [<Type{,Type}>] 返回类型方法名([参数列表]) [throws exceptionList] { 方法体 } abstract: 抽象方法 native: 用来集成java代码和其他语言代码 synchronized: 控制多线程对共享数据的访问
按是否被static修饰
实例方法
类方法(静态方法)
static方法属于整个类 不能操作和处理实例变量 不能使用this和super 只能处理类变量/调用类方法
主方法
public static void main ( String[] args ) { //方法体 } 必须位于public类中 Java编译器通过主方法来执行程序 *静态/无返回值/形参为数组
其他特殊方法
不能按是否被static修饰而分类的方法 如构造方法,不能被static修饰,而又不同于一般的实例方法
构造方法
用于对象初始化 *与类同名 *无返回值 *未定义时,系统将提供默认构造方法(无参) *定义后,系统将不会提供任何默认构造方法 *通常声明为public *不能显式调用,由系统自动调用 无参构造函数的重要性: 若无该方法,则子类声明中必须含有构造方法,系统将不再提供默认构造方法 
this关键字
可用于在一个构造方法中调用另一个, 且必须是构造函数中的第一句 
访问控制权限
public: 任何类都可以访问 protected: 子类可访问(不在同包中的子类也可以) private: 其他类均不可访问 default(默认权限): 包访问权限,同package就可以访问 
对象的声明与引用
仅仅声明引用变量“声明该变量将会存一个地址”时并没有生成对象 需要new出来 类名 变量名=new 类名(); *引用变量也可以被赋以空值
类的组织
包(Package)
不可嵌套 管理类名空间,解决类名冲突,相当于一个装类的文件夹 松散的类(编译单元)的集合 同包内类名不可重复
编译单元
一个Java源代码文件即为一个编译单元
所属包的声明
package xxx;
引入包的声明
import package1[.package2...].( classname |* ); 同包中的类可以相互引用,不必import
类和接口的声明
命名规则
包名必须独一无二 包名全小写 
包的声明
命名的包:package xxx; 默认包:不含有包声明的编译单元属于 default package (eclipse中)
枚举类型
声明: [public] enum枚举类性名称[implements接口名称列表] { 枚举值; //逗号隔开 变量成员声明及初始化; 方法声明及方法体; //构造方法必须为private修饰 } *枚举值使用toString()方法可以输出字符串 使用: 枚举类型名.枚举值 
方法
方法的控制流程
基本与C++相同
顺序结构
选择结构
循环结构
增强for循环
eg: for( int item : numbers ){ //循环体 }
break和label
public static void main(String[] args){ outer: for (int i=1; i<=9;i++) { for (int j=1; j<=9; j++){ if (j > i) break; if (i==6) break outer; System.out.print(" "+i+"*"+j+"="+i*j); } System.out.println(); } }
continue和label
和break/label使用格式一致
异常
异常和错误类的层次结构
Object-->Throwable
Error
由Java虚拟机生成并抛出,Java程序不处理Errors VirtualMachineError StackOverflowError OutOfMemoryError ......
Exception
由应用程序处理或输出
非检查型异常
RuntimeException 由系统检测,用户可不作处理 NullPointerException ArithmeticException IndexOutOfBoundsException NegativeArraySizeException ArrayIndexOutOfBoundsException ArrayStoreException ......
检查型异常
checked exception,需要用户处理 ClassNotFound DataFormat FileNotFoundException IOException ......
异常处理的方法
不处理将会抛至主方法中
抛出(throw)异常
消极的异常处理机制 抛出异常的方法需要在声明中写上 throws 异常类型名 子句
捕获(catch)异常
try {} catch (){ //常用方法 getMessage(); toString(); printStackTrace();//给出方法的调用序列,直到异常的产生位置 } finally{} *特殊异常放在一般异常前捕获
生成异常对象
实现:(异常对象必须是Throwable或其子类) throw new Throwable();
Java虚拟机生成
Java类库中的类生成
自定义异常类
public class MyExceptionName extends SuperclassOfMyException{ public MyExceptionName() { super("Some string explaining the exception"); } }
类的重用
继承
is-a 子类是父类的特殊化,Java只支持单继承 class childClass extends parentClass { //类体 } *子类访问父类中的成员可用super.
隐藏与覆盖
属性隐藏(hiding)
子类中有与父类中同名的变量 则从父类继承的变量将被隐藏 只有当执行从父类继承的操作才使用继承变量 (因而,子类也可修改父类的类变量) 属性不存在覆盖,只有引用对象决定
方法覆盖(overriding)
子类定义与从父类继承来的方法同名、同参的方法 覆盖方法的访问权限不能比被覆盖的严格 理解:原则上为了动态绑定、多态性 因为子类是父类的特殊化,是对父类的拓展,所以访问权限不能变小 eclipse:在函数前加@Override
抽象方法必须被覆盖
否则派生类也成了抽象类
final方法和static方法不可覆盖
同名static方法,父类中的将会被隐藏
覆盖方法和隐藏方法
覆盖方法由调用对象实体决定
隐藏方法调用由调用对象引用决定
有继承时的构造方法
构造方法无法被继承 子类构造方法的第一行必须.super调用父类的构造方法 (否则将调用父类的无参构造方法)
final
不可再变的
数据
不可修改,只能被赋值一次 (final 可以修饰局部变量,但static不行) 同时被static final修饰,表示类常量 static会‘给’该变量缺省值
类
不能被继承 如:String和Math
方法
不能被子类重写(覆盖) 提高安全性和正确性 提高运行效率:final方法将会被内联(inline) (方法体太长也会放弃内联) 类中的private隐式指定为final
abstract
抽象类
不能被实例化
抽象方法
只需声明“;” 不需方法体“{ }” *抽象类可以不含抽象方法 *抽象方法只能出现在抽象类中 *抽象方法必须在子类中被实现 (否则子类仍为abstract,无意义)
泛型(Generics)
类似C++模板: 声明: public class Box<T> { private T t; // T stands for "Type" public void add(T t) { this.t= t; } public Tget() { return t; } } 使用: Box<Integer>intBox = new Box<Integer>(); *有限制的泛型:public class Box<T extends Number>
泛型的继承
参考链接:https://www.cnblogs.com/lihaoyang/p/7104293.html
保留父类泛型
子类也为泛型
全保留
部分保留
不保留父类泛型
子类可以按需拓展为泛型 或不写成泛型,直接擦除泛型
具体类型替代
泛型擦除
类组合
has-a
Java基础类库简介
语言包( java.lang )
不需要import
Object类
Java所有类的祖先类
主要方法

getClass()
返回Class对象 不可重写
equals()
== 判断是否同一 (如果只需要判断相同,则可重写equals()方法)
相等
两个对象具有相同的类型,及相同的属性值
同一
两个引用变量指向同一个实体对象 (用 ' == ' 判断)
数据类型包裹类
为基本数据类型添加对应的类, 使基本数据类型可使用方法 用包裹类.valueOf(字符串); //手动装箱:把字符串转为对应包裹类对象 用包裹类对象.intValue(); //手动拆箱,返回int基本数据类型 用包裹类.parseInt(字符串); //手动拆箱,返回int基本数据类型 Java已支持自动拆/装箱 
String类
常量字符串:值和长度都不变化 构造方法  length()方法返回长度
StringBuffer类
可以修改的字符串,方法不可与String混用 比String效率更高 字符的个数:length 分配的存储空间:capacity 
chatAt(int index)
返回对应下标的字符
reverse()
append(Object ob)
将ob接到字符串后
字符串类
Math类
所有的变量和方法都是静态的(static) 是终结类
System类

Runtime类
Runtime run=Runtime.getRuntime(); run.totalMemory();  以字节为单位
系统和运行时类
Class类
getName()
getSuperclass()
ClassLoader类
提供把类装入运行时环境的方法
类操作类
实用包 ( java.util )
Date类
 Date类可以直接输出
Calendar类
抽象类,不能new, 使用getInstance()方法创建一个GregorianCalendar类的对象 Calendar c = Calendar.getInstance(); //返回子类对象
GregorianCalendar类
Calendar的派生类 
日期类
集合类
Java集合框架,第七章详细展开
Collection 无序集合
Set 不重复集合
List 有序不重复集合
Enumeration 枚举
LinkedList 链表
Vector 向量
Stack 栈
Hashtable 散列表
TreeSet 树
StringTokenizer类
建议用String中的split方法 
文本包( java.text )
Format类
DateFormat类
SimpleDateFormat类
 
JAR( Java Archive )
类似ZIP文件, 但JAR文件中包含了 META-INF/MANIFEST.MF文件 部署描述符 
可执行的JAR文件包
接口与多态
接口(interface)
形式上与类类似,但可以实现多继承 命名一般为able结尾 在UML图中用虚线表示接口关系 (理解为对象间的通讯协议,在对象之间架起通用的桥梁)
接口的语法
声明
[public|default] interface 接口名称[<Type{,Type}>][extends 父接口列表] { …//方法的原型声明或静态常量 } *可包含基本数据类型的数据成员,默认被public/static/final修饰,且必须赋值 *方法必须为抽象方法(可以省略public/abstract) *只规定方法声明,不规定方法体 (Java8之后用static修饰的方法可以规定方法体)
实现
不能new,只能利用实现该接口的类来创建对象 对象可以转型成其所属类实现的接口的类型 interfaceType interfaceName=(interfaceType) new ClassType|(); class 类名称 implements 接口名称 { /* Bodies for the interface methods */ /* Own data and methods. */ } *必须实现接口中的所有方法 *来自接口的方法必须声明成public
多重继承
一个类可以实现多个接口
接口的扩展
即接口的继承 *接口可以继承多个接口 *实现接口的类必须实现该接口的所有接口
多态(Polymorphism)
对不同类型的对象进行同样的操作 使程序具有可扩展性
塑型(type-casting)
广义而言,以下情况都算塑型: 类型转换 基本数据类型 引用变量
向上塑型
把子类对象赋值给父类类型的变量,或对象所属类的接口 是自动类型转换 从具体到一般,方法会变少
向下塑型
只有在该对象原本就是向上塑型的情况才能向下塑型(还原) 显式类型转换 从一般到具体 可用instanceof运算符进行判断
应用场合
赋值转换
方法调用转换
算术表达式转换
字符串转换
绑定(Binding)
类似C++的静态联编与动态联编 实现多态的机制 在Java中所有被重写的方法都称为虚方法
早期绑定
运行前
晚期绑定
动态绑定:运行时的虚方法调用 (有private,final,static修饰均不可被重写,不是虚方法,同理构造方法也不是虚方法)
输入输出
步骤: 打开一个读/写流 读/写信息 关闭读/写流 不关闭可能会导致缓冲流中的内容没有全部写入文件中 使用的基础类都在java.io中
输入输出流
按流向分
输入流
读
输出流
写
按分工分
节点流
直接连接数据源读写 从使用层面看,直接new出来就能用
处理流
链接到其他流,过渡作用,增强节点流的功能 从使用层面看,new的时候里面必须要套点东西
按内容分
所有的数据输入输出最后都归为字节流 字符流必须传入字节流作为参数才能使用 字符流算是上层建筑 字节流是地基
面向字节
处理字节,用于一般目的 只能读字节(数字)
InputStream

FileInputStream
PipedInputStream
多线程通过管道进行通讯
FilterInputStream
LineNumberInputStream
DataInputStream
BufferedInputStream
缓冲流的原理: 直接从硬件读取速度慢,从内存读取速度快 在内存中建立缓冲区,把硬件中的字节读取到内存中(并不是读了就用) 等待程序调用,再从内存的缓冲区读入程序 (好比水缸,单纯的点对点字节流用一次去水井打一次水, 用于缓冲的处理流是一个大水缸,先一次性装满,这样程序再读取时就不用 反复跑去水井“取水”了)
PushbackInputStream
ByteArrayInputStream
SequenceInputStream
StringBufferInputStream
ObjectInputStream
OutputStream

FileOutputStream
PipedOutputStream
FilterOutputStream
DataOutputStream
BufferedOutputStream
PrintStream
ByteArrayOutputStream
ObjectOutputStream
面向字符
处理字符 专门用于处理字符数据 实现内部格式和文本文件中的外部格式之间转换
Reader
BufferedReader
不能直接处理System.in
LineNumberReader
CharArrayReader
InputStreamReader
读取字节转换为字符
FileReader
FilterReader
PushbackReader
PipedReader
StringReader
Writer
BufferedWriter
CharArrayWriter
OutputStreamReader
FileWriter
FilterWriter
PipedWriter
StringWriter
FilterWriter
标准输入输出
System类的静态成员变量
System.in
是System的类变量,声明时为InputStream类(抽象类) 线程开始时将会被初始化为BufferedInputStream类实例 “setIn0(new BufferedInputStream(fdIn))” 所以可以调用read()等方法 键盘输入
System.out
PrintStream类,直接就可以用 屏幕输出
System.err
PrintStream类,标准错误信息输出流 屏幕输出
文件读写
读写二进制文件
用字节流 二进制文件:内容应被理解为出了字符以外的东西 (如图片、音乐......)
InputStream
抽象类
FileInputStream
FilterInputStream
DataInputStrean
遇到文件尾会抛出EOFException异常
readInt()
readDouble()
readBytes()
BufferedInputStream
OutputStream
抽象类
FileOutputStream
节点流
FilterOutputStream
DataOutputStream
处理流
writeInt()
writeDouble()
writeBytes()
BufferedOutputStream
用于在中间过程中缓冲
读写文本文件
文本文件:所有内容都应被解释为字符
Reader
BufferedReader
读到文件尾返回null
readline()
鉴别换行符
InputStreamReader
FileReader
read()
文件尾返回-1
Writer
BufferedWriter
newline()
用于换行
OutputStreamReader
FileWriter
FileWriter fw=new FileWriter(String fileName,boolean append)
write()
File类
用于操纵文件 
构造方法

常用方法

对象序列化
不保存对象的transient和static变量 因为序列化保存的是对象的状态,而非类的状态,也不是对象的临时状态 想要实现序列化的对象,其类必须实现Serializable接口 (该空接口用于标记作用)
ObjectInputStream
readObject()
有时需要显式类型转换
ObjectOutputStream
writeObject()
随机文件读写
文件中记录等长
RandomAccessFile
实现了DataInput和DataOutput接口 位置指示器指向当前读写处的位置 可同时支持读写操作 
int skipBytes(int n)
把文件指针向前移动n个字节
void seek(long)
移动文件指针到指定的位置
long getFilePointer()
得到当前的文件指针
read()
按字节读,文件尾返回-1
writeChar(int v)
写入一个字符/两个字节(Java采用Unicode编码,1字符=2字节)
对象群体的组织
数组
优点:支持随机访问,速度较快 缺点:创建后大小固定,每个元素类型相同
基本数据类型数组
对象数组
数组实用方法

集合(集合框架)
集合: 大小动态可变 可以存储不同类型的数据 Java中和集合有关的类和接口被组织起来 这种层次框架被称为集合框架(泛型实现) 作用类比C++ STL(容器/算法/迭代器)
数据结构与实现
Interfaces
集合的抽象数据类型(泛型)
Iterable
Collection
声明了查询方法和修改方法 查询方法:  修改方法: 
Set
元素不可重复,无序 重写了equals方法 包含同样元素的两个Set相等
SortedSet
元素升序排列的接口 通常用于存放类似词汇表的内容
List
可包含重复元素,有序索引
Queue
Map
键值对映射 双射,键不可重复 查询方法:  修改方法: put(Object key,Object val)
SortedMap
关键字升序排列的接口 通常用语词典和电话目录
Implementations
实现集合接口的Java类,可重用的数据结构
HashSet
TreeSet
实现SortedSet接口
Set
Vector
Stack
ArrayList
add()方法添加元素 get(i)获取下标为i的元素
LinkedList
List
ArrayList/Vector能存储任意对象 但不能存储基本类型(需要装箱) 只存储指定类型时可以将泛型确定 ArrayList<String>myList=new ArrayList<String>(); Vector同步且线程安全,但已不推荐使用 ArrayList非同步,效率高
ArrayDeque
PriorityQueue
Queue
HashMap
TreeMap
实现了SortedMap接口
Map
Algorithms
算法 大多数用于操作List对象
排序算法sort
对List进行排序 1.自然序 2.自定义Comparator对象
洗牌算法shuffle
用于List,打乱算法
数据处理算法
查找算法binarySearch
寻找最值
min
max
Iterator
(优于Enumeration接口,推荐使用) 迭代器接口,用于遍历集合 Iterator<ClassType>it=Object.iterator(); Object中存储的ClassType类型
hasNext()
判断是否还有元素
next()
取得下一个元素
remove()
从集合中去除Iterator当前(指向的)返回的元素
多线程
编程基础
线程和进程
进程(Process)
定义:独立程序的一次运行 进程间的通信较麻烦
线程 (Thread)
多线程:同一个进程中多段代码并发执行 线程间的通信较容易 Java是第一个内置多线程操作的主流编程语言
线程的实现
Thread类
创建多线程可以继承Thread类 位于java.lang包中,Thread类已经实现了Runnable接口 实用方法: 1.创建实例,调用start()方法即可 2.new Thread(多线程类).start()
构造方法
1.public Thread(); 2.public Thread(Runnabletarget); 法二会反复调用同一个实例的run()方法 方便实现多线程之间的数据共享 3.public Thread(Stringname) StringName为线程名
重写run()方法
在该方法中写入线程需要执行的语句
start()
调用,使线程开始执行 会自动调用run()方法
sleep(long millis)
让线程睡眠 millis 毫秒 Thread.sleep(n)默认让主线程休眠
yield()
暂停当前线程(放弃执行权) 放弃多久不一定
currentThread()
返回当前正在运行的线程对象
Runnable接口
创建多线程可以实现Runnable接口 接口中只含有一个run()方法 用于为已有基类的类生成多线程 (Java不支持多继承)
线程间共享
代码共享
多个线程的执行代码来自同一个类
数据共享
访问相同的对象 例如用同一个实现了Runnable接口的实例作为参数创建多线程 即可实现这些线程之间的数据共享
多线程同步控制
同步机制:监视器
互斥
同一时刻只有一个线程访问该共享数据 监视区:在同一时刻只能被一个线程执行的方法或代码
协作
允许别的线程在一定条件下进入监视区
synchronized
线程同步关键字
同步对象
使用:synchronized ( Object ) { 监视区代码段 } 机制: 1.判断对象锁旗标是否存在 存在就获得锁旗标 不存在进入等待状态,直至获得锁旗标 2.获得锁旗标后执行监视区代码 3.执行完毕后释放锁旗标
同步方法
用于互斥方法 使用:piblic synchronized void xxx(){} 两个方法同一时间只能有一个在执行 (不论有几个线程)
线程间通信
java.lang.Object类的一些方法
wait()
进入等待池,释放锁旗标 直到其他线程在对象x上调用notify()类方法才可能 再重新获得锁旗标(有时需要等待)继续执行,从wait()语句之后继续
notify()
随机唤醒一个等待池中的线程 本线程继续执行
notifyAll()
唤醒所有等待线程
后台线程(Daemon Thread)
又称“守护线程” 只要有前台线程,守护线程就不会结束 一旦没有前台线程,守护线程(无论是否执行完毕)都会结束 如:垃圾回收 调用Thread类的setDaemon(true)方法使线程变成守护线程
线程的生命周期
一个线程在任何时刻都处于某一种线程状态 
新建(New)
就绪(Runnable)
执行start() 是一个瞬时状态
运行(Running)
阻塞(Blocked)
进入wait()池,主动调用wait() 进入lock()池,未获得锁旗标 休眠,主动调用sleep()
死亡(Dead)
线程优先级
线程调度
控制多个线程在同一个CPU上以某种顺序运行称为线程调度
固定优先级算法
优先级范围 [1,10],值越大优先级越高,值相同顺序随机 每个线程的默认优先级为5 线程运行过程中创建的新线程与其具有相同的优先级 后台->后台 改变优先级setPriority(int priority)
线程暂停运行
具有更高优先级的线程就绪
调用某些特定方法
时间片的时间期满
其他tips
java中同名局部变量不存在屏蔽问题,只会报错
此特性与其他编程语言不同 如下例,会报错 int x=1; for(int x=0 ; x<5 ; x++){ }
位运算符
~
按位反
&
同真为真
|
按位或
^
按位异或
移位运算符
分类
>>
左移运算符
低位补零
左移n位相当于乘以2的n次方
<<
右移运算符
高位补高位
右移n位相当于除以2的n次方
>>>
无符号右移运算符
高位补零
tips
适用范围
整型和字符型
低于int将先自动升为int
a>>b=a>>(b mod 32)
移位不改变变量
背单词