JavaSE| 数据类型| 运算符| 进制与补码反码等
JavaSE
JavaSE是学习JavaWeb、JavaEE以及Android开发的基础
捷径:敲、狂敲; 规范:加注释;
难点,不懂的记录下时间再回头看;
在敲代码中学习知识点,加深知识的理解。
1.基础常识
软件开发:
软件,即一系列按照特定顺序组织的计算机数据和指令的集合。分为系统软件和应用软件。
人机交互方式:
图形化界面(Graphical User Interface GUI)这种方式简单直观,使用者易于接受,容易上手操作。
命令行方式(Command Line Interface CLI):需要有一个控制台,输入特定的指令,让计算机完成一些操作。需要记住一些命令。
常用的DOS命令
dir:列出当前目录下的文件以及文件夹
mid:创建目录
rd:删除目录
cd:进入特定目录
cd..:退回到上一级目录
cd\:退回到根目录
del:删除文件
exit:退出dos命令
echo javase >1.doc
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
C:\Users\Administrator>d: D:\>directory 'directory' 不是内部或外部命令,也不是可运行的程序 或批处理文件。 D:\>dir 驱动器 D 中的卷没有标签。 卷的序列号是 0004-E52B D:\ 的目录 2018/11/04 22:47 <DIR> 140415 2018/11/04 19:22 <DIR> BaiduYunDownload 2018/07/21 15:31 <DIR> centos7 2018/11/05 10:26 <DIR> code 2018/06/08 20:39 <DIR> Git 2017/11/28 11:34 <DIR> photoshop_cs6_33lc 2018/11/05 10:55 <DIR> Program Files 2018/09/26 20:58 <DIR> Program Files (x86) 2018/05/12 08:44 <DIR> WebStorm 2018.1.3 2018/08/03 22:06 <DIR> WeChat 2017/01/11 22:56 510,835,180 文件.rar2018/07/21 15:33 <DIR> 虚拟机 1 个文件 510,835,180 字节 12 个目录 113,653,895,168 可用字节 D:\>md 1130 #创建文件夹 D:\>cd 1130 #切换到这个文件目录下 D:\1130>md team1 #创建文件 D:\1130>md team2 D:\1130>cd.. #退出1层目录 D:\>cd 1130/team1 #进入多层目录 D:\1130\team1>cd.. D:\1130>cd/ #退出到根目录 D:\>cd 1130\team1 D:\1130\team1>echo name:kris sex:male > 1.txt #创建文件并写入内容 D:\1130\team1>echo >1.doc D:\1130\team1>cd.. D:\1130>rd team2 #删除目录 D:\1130>rd team1 目录不是空的。 D:\1130>cd team1 D:\1130\team1>del 1.doc #删除文件 D:\1130\team1>del *.doc 找不到 D:\1130\team1\*.doc D:\1130\team1>cd.. D:\1130>del team1 D:\1130\team1\*, 是否确认(Y/N)? y D:\1130>rd team1 D:\1130>
计算机语言:
语言:人与人沟通的一种方式。中国人要和英国人交流就要学习英语。(更多的是一种形象思维)
计算机语言:人与计算机交流的方式。人与计算机交流就要学计算机语言,如C、C++、java、php等。
2.Java语言概述
C语言主要用来写操作系统,也可写应用软件,但超过十万行代码的用的就比较少了,它对异常处理机制、错误处理做的不好;它不是面向对象的,虽然有很好的运行效率
; C++具有一些面向对象的特性,社区的回复性也很高,但它不是跨平台的;
Java是跨平台的;C#跨平台性、面向对象都有,它是微软搞出来的。
重量型(C、java、objective--C、C++、C#)注重运行效率,功能性;、轻量型级别(PHP、python、JavaScript、Visual Basic .NET)讲究开发的效率,可移植性、跨平台性较差。
Java语言的主要特性
特点一:面向对象
两个基本概念:类、对象
三大特性:封装、继承、多态
提供类、接口和继承等原语,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为implement)。
特点二:分布式
支持Interner应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocker等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
特点三:健壮性
吸收了C/C++语言的优点,但去掉了其影响程序健壮性的部分(如指针、内存的申请与释放等),提供了一个相对安全的内存管理和访问机制。
强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。
特点四:跨平台性
跨平台性:通过java语言编写的应用程序在不同的系统平台上都可以运行。“ Write once , Run Anywhere ”;
原理只要在需要运行java应用程序的操作系统上,先安装一个Java虚拟机(JVM Java Virtual Machine)即可。由JVM来负责程序在该系统中的运行。
JAVA程序 -- win版JVM(windows操作系统)、linux版的JVM(Linux操作系统)、Mac版的JVM(Mac操作系统)
因为有了JVM,同一个Java程序在三个不同的操作系统中都可以执行。这样就实现了Java程序的跨平台性。
Java技术体系平台
Java SE(Java Standard Edition)Java标准版
支持面向桌面级应用(如Windows下的应用程序)的Java平台,提供了完整的Java核心API,此版本以前称为J2SE
Java EE(Java Enterprise Edition)Java企业版
是为开发企业环境下的应用程序提供的一套解决方案。该技术体系中包含的技术如:Servlet 、Jsp等,主要针对于Web应用程序开发。
Java ME(Java Micro Edition)Java小型版
支持Java程序运行在移动终端(手机、PDA)上的平台,对Java API有所精简,并加入了针对移动终端的支持,此版本以前称为J2ME
Java Card
支持一些Java小程序(Applets)运行在小内存设备(如智能卡)上的平台
JVM、JRE、JDK的介绍
JDK(Java Development Kit Java开发工具包) JDK = JRE + 开发工具包
JDK是提供给开发人员使用的,包含了Java的开发工具(编译工具(javac.exe)打包工具(jar.exe)等),也包括了JRE。
JRE(Java Runtime Environment Java运行环境) JRE = JVM + JavaSE标准类库
包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,如果想运行一个开发好的java程序,只需安装JRE即可。
简单而言,使用JDK的开发工具完成的java程序,交给JRE去运行。
JVM Java Virtual Machine java虚拟机
JDK是包含JRE的,JRE java运行式环境,仅仅是用来运行,它里边包含Java虚拟机以及所需的主要库;
include是示例,jre整个运行式环境,bin涉及一些命令;命令对应的代码在lib里边;bin可执行文件(javac编译、java运行)
配置环境变量,就是可以在任何目录下运行;
Java应用程序的开发
D:\code\day01>javac HelloWorld.java //编译之后就会出现HelloWorld.class的文件 D:\code\day01>java HelloWorld //类名 Hello Java!
编译 .java文件--->.class文件 JVM
解释 JVM ->机器
public class HelloJava{ /* 1.源文件以.java结尾; 2.源文件中可以有多个class声明的类; 3.类中可以有主方法(即main()方法,其格式是固定的:public static void main (String[] args){} 4.main()方法是程序的入口,方法内是程序的执行部分; 5.一个源文件中只能有一个声明为public的类,同时要求此类的类名与源文件名一致。 6.每个语句都以";"结束 7.执行程序:编译:javac.exe ,编译完生成诸多个.class字节码文件;运行:java.exe */ public static void main(String[] args) { System.out.println("Hello World!"); } } class Person{ } class Hello{ }
注释
提高代码的阅读性,调试程序的重要方法。有单行注释、多行注释(不能嵌套)、文档注释(java特有)。将自己的思想通过注释先整理出来,再用代码去体现。(良好的编程习惯)
文档注释(java特有)
格式:
/** *@author 指定java程序的作者 *@version 指定源文件的版本 *@param 方法的参数说明信息。 */
注释内容可以被JDK提供的工具javadoc所解析,生成一套以网页文件形式体现的该程序的说明文档。
操作方式:
D:\code\day01>javadoc -d mydoc -author -version HelloJava.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
D:\code\day01>javadoc -d mydoc -author -version HelloJava.java 正在加载源文件HelloJava.java... 正在构造 Javadoc 信息... 正在创建目标目录: "mydoc\" 标准 Doclet 版本 1.8.0_192 正在构建所有程序包和类的树... 正在生成mydoc\HelloJava.html... 正在生成mydoc\package-frame.html... 正在生成mydoc\package-summary.html... 正在生成mydoc\package-tree.html... 正在生成mydoc\constant-values.html... 正在构建所有程序包和类的索引... 正在生成mydoc\overview-tree.html... 正在生成mydoc\index-all.html... 正在生成mydoc\deprecated-list.html... 正在构建所有类的索引... 正在生成mydoc\allclasses-frame.html... 正在生成mydoc\allclasses-noframe.html... 正在生成mydoc\index.html... 正在生成mydoc\help-doc.html... D:\code\day01>
API
源码:
D:\Program Files\Java\jdk1.8.0_192\src.zip 在这个压缩包里边,把它的代码给抽取出来就是我们看到的API,类--下面的一些方法;
文档中英文结合地看;
3.基本语法
关键字、标识符、变量(基本数据类型和基本数据类型转换)、运算符、程序流程控制、数组
3.1 关键字、保留字
定义:被java语言赋予了特殊含义,用做专门用途的字符串(单词); 特点:关键字中所有字母都是小写;
用于定义数据类型的关键字:
class、interface、enum、byte、short、int、long、float、double、char、boolean、void
用于定义数据类型值的关键字:
true、false、null
用于定义流程控制的关键字:
if、else、switch、case、default、while、do、for、break、continue、return
用于定义访问权限修饰符的关键字:
private、protected、public
用于定义类,函数,变量修饰符的关键字:
abstract、final、static、synchronized
用于定义类与类之间关系的关键字:extends、implements;
用于定义建立实例及引用实例,判断实例的关键字:new、this、super、instanceof
用于异常处理的关键字:try、catch、finally、throw、throws
用于包的关键字:package、import
其他修饰符关键字:native、strictfp、transient、volatile、assert
java保留字:现有Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标记符时要避免使用这些保留字。
byValue、cast、future、generic、inner、operator、outer、rest、var、goto、const
3.2 标识符
Java对各种变量、方法和类等要素命名时使用的字符串系列成为标识符。 凡是自己可以起名字的地方都叫标识符。
定义它的规则
①由26个英文字母大小写,0--9,_或$组成;②数字不可以开头;
③不可以使用关键字和保留字,但能包含关键字和保留字;
④ Java中严格区分大小写,长度无限制。
⑤中间不能有空格
标识符的命名规范
1、见名知意
2、类名、接口名:每一个单词的首字母大写,形式:XxxYyyZzz
3、变量名、方法名:从第二个单词开始,首字母大写,形式:xxxYyyZzz
例如:main, getName, age, myAge
4、包名:所有单词都小写,单词之间使用.分割,形式:xxx.yyy.zzz
例如:java.util,java.sql,java.lang,java.net
5、常量名:所有单词都大写,单词之间使用_分割,形式:XXX_YYY_ZZZ
例如:PI,MAX_VALUE,MAX_PRIORITY
53个关键字、保留字、特殊值:都是小写。
3.3 变量
变量:存储值、访问值; 用一个固定的名字,代表一个会变的值。
变量:本质上代表内存中的一块存储区域(该区域有自己的名称(变量名)和类型(数据类型)),这块存储区域中的值是可变的。
变量有三个要素:
(1)数据类型 比喻房间的类型,单人间,双人间,总统套房
(2)变量名 比喻房间号,302,312
(3)变量值 比喻房间中的人,张三,李四
如何声明一个变量?
数据类型 变量名; //占用名称,并且确定类型
变量的使用有要求:
(1)先声明后使用
如果一个变量没有声明:
TestVariable.java:27: 错误: 找不到符号
(2)在使用之前,必须先初始化
使用:包括计算、打印值
(3)变量有作用域
A:同一个作用域中,变量不能重复声明,可以重复赋值
B:出了作用域,变量就无法访问了
作用域:从声明处开始,到它所属的{ }结束
该区域的数据可以在同一类型范围内不断变化;
定义变量的格式:数据类型 变量名 = 初始化值;
变量的分类(按数据类型分)
对于每一种数据都定义了明确的具体数据类型,在内存中分配了不同大小的内存空间。
① 整数类型:byte、short、int、long
Java各整数类型有固定的表数范围和字段长度,不受具体OS的影响,以保证java程序的可移植性。
整型常量默认为 int 型,声明long型常量须加 ‘ l ’ 或 ‘ L ’
② 浮点类型 float、double
浮点型: float:单精度浮点型,占4个字节 大概科学记数法的表示方式,小数点后6~7位,前6位是精确的。 double:双精度浮点型,占4个字节 大概科学记数法的表示方式,小数点后15~16位,前15位是精确的。
③字符类型:char
char:字符类型,Java是存储每一个字符的Unicode编码值,2个字节 世界上所有的字符、标点符号都会有一个唯一的Unicode编码值。 A:65 B:66 a:97 b:98 0:48 1:49 尚:23578(十进制) Unicode的数字值占个字节,但是在网络中传输、文件中保存实际占几个字节,要看编码方式:GBK,每一个汉字都是2个字节UTF-8,每一个汉字基本上是3个字节,也有特殊的。 char字符的表示方式: (1)'a','男',';' 字符常量是用单引号(‘ ’)括起来的单个字符,涵盖世界上书面语的字符, 例如:char c1 = 'a';char c2 = '中';char c3 = '9'; (2)'\n','\t','\b' 转义字符。Java中还运行使用转义字符 ‘ \ ’来将其后的字符转变为特殊字符型常量。例如:char c3 = ' \n '; // '\n'表示换行符。 (3)'\u5c1a' 十六进制。直接使用Unicode值来表示字符型常量:‘\uXXXX’。其中,XXXX代表一个十六进制整数,如:\u000a 表示\n。
char类型是可以进行运算的。因为它都对应有Unicode码。
转义字符
\b 退格键
\n 换行符
\r 回车符
\t 制表符
\" 双引号
\' 单引号
\\ 反斜杠
ASCII对照表
④布尔类型:boolean 逻辑值
适于逻辑运算,一般用于流程控制:
if条件语句; while循环控制语句; do-while循环控制语句; for循环控制语句;
boolean 类型数据只允许取值true和false,无null;不可以0或非0的整数替代false和true,这点和C语言不同。
⑤ 引用数据类型
引用数据类型:
类、:例如:String,System,Object,Math,File,Date,Scanner.....
接口:Runnable、Serializable、Comparable....
数组:int[],String[],char[]....
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//变量: 基本数据类型(8个) vs 引用数据类型(类、接口、数组) //1.java中的变量定义的格式: 数据类型 变量名 = 初始值 class TestVeriable{ public static void main(String[] args) { //2.变量先定义,后使用 int myInt1 = 10; double d1 = 12.3; System.out.println(myInt1); System.out.println(myInt1 + d1); //i1超出了其作用范围,不可使用。 //System.out.println(i1); //3.整型:byte(-128~+127) short int(默认类型) long byte b1 = 12; byte b2 = 127; short s1 = 128; int i1 = 12; //定义long型变量,值的末尾加"L"或"l" long l1 = 12324321L; System.out.println(l1); //4.浮点型(带小数点的数值):float double(默认类型) double d11 = 12.3; //声明float类型的浮点型数据,末尾要加"F"或者"f" float f1 = 12.3F; System.out.println(f1); //5.字符型(=两个字节): char 只能表示一个字符(英文、中文,标点符号等) char c1 = 'a'; //char c2 = 'ab'; String str = "ab"; char c3 = '中'; String str1 = "中国"; //可以表示转义字符 char c4 = '\t'; char c5 = '\n'; System.out.println("abc" + c5 +"def"); char c6 = '\u1234'; System.out.println(c6); //6.布尔类型: boolean 只能够取值true 或 false,不能取值null boolean bool1 = true; if(bool1){ System.out.println("你看帅哥!"); }else{ System.out.println("没看到!"); } } public void method1(){ int i1 = 10; System.out.println(i1); } }
3.4 数据类型的转换
(1)自动类型转换 byte,short,char-->int-->long-->float-->double A:byte与byte,short与short,char与char进行运算,会升级为int B:byte与short,byte与char等混合运算,也会升级为int C:所有类型混合运算,会自动升级为参与类型中最大的那个 D:boolean不参与任何类型转换 E:所有类型一旦与String进行“+”拼接,结果都是String (2)强制类型转换 double-->float-->long-->int-->byte,short,char A:把存储范围大的数据类型的值或变量赋值给存储范围小的变量,那么需要强制类型转换,用(),-32768~32767; 但是强制类型转换有风险,可能会溢出或损失精度。 B:有的时候需要把某个存储范围小的类型,强制转为大的类型,进行运算 int a = 1; int b = 2; System.out.println("a / b = " + (double)a/b); C:boolean不参与任何类型转换 D:String不参与强制类型转换 short是2个字节,-32768~32767 char是2个字节,无符号的整数值,0~65535
/* 变量之间的运算:(不考虑boolean,剩下char(都对应unicode的一个值) byte short int long float double) 1.自动类型转换 2.强制类型转换 */ class TestVeriable1{ public static void main(String[] args) { //1.自动类型转换:当容量小的数据类型与容量大的数据类型做运算时,容量小的会自动转换为 //容量大的数据类型:char,byte,short==>int==>long==>float==>double int i1 = 12; //4个字节 short s1 = 2; //2个字节 int i2 = i1 + s1; //4个字节 float f1 = 12.3F; float f2 = f1 + i2; double d1 = f2 + 12.3;//默认12.3为double类型,8个字节,如果用float就错了 long l = 12L; //long l = 12; 默认为int类型,赋值给l也是可以的,int范围比long的小 float f3 = l; //这种形式的也可以.用的是科学计数法 char c1 = 'a';//97 c1 = 'A';//65 int i3 = c1 + 1; System.out.println(i3); System.out.println(i2); System.out.println(f2); //需要主意的:当char\byte\short之间做运算时,默认的结果为int类型 short ss1 = 12; byte bb1 = 1; char cc1 = 'a'; //short ss2 = ss1 + bb1; 错误的 int ii1 = ss1 + bb1; //char cc2 = cc1 + bb1; 错误的 int ii2 = cc1 + bb1; short ss2 = 11; //short ss3 = ss1 + ss2 //2.强制类型转换:容量大的转换为容量小的 //强制类型转换的问题:导致精度的损失 long l1 = 12345L; int m1 = (int)l1; System.out.println(m1); byte by1 = (byte)m1; System.out.println(by1); //3. 平时常用的字符串,也是一种数据类型:String String nation = "我是一个中国人"; System.out.println(nation); //字符串与数据类型之间的运算:只能是连接运算: + ,得到的结果仍为一个字符串 String str = "abc"; String str1 = str + m1; //abc12345 //String.out.println(str1); 这里为什么说找不到符号?????????????????? m1?? //题目: String str11 = "Hello"; int myInt1 = 12; char ch1 = 'a'; //97 System.out.println(str11 + myInt1 + ch1);//Hello12a System.out.println(myInt1 + ch1 + str11);//109Hello System.out.println(ch1 + str11 + myInt1);//aHello12 } }
3.5 二进制与补码反码
计算机的底层所有的数据都是用二进制来存储的。 我们的整数当然也是用二进制存储的。 单位: bit:位 一个二进制的位,要么是0要么是1,是计算机中最小的存储单位; byte:字节 一个字节是8位,是计算机最基本的存储单位; 1KB = 1024字节 1MB = 1024KB 1GB = 1024MB 1TB = 1024GB .... 1个字节是8位,存储的范围是多少? 计算机底层存储数字,用补码存储。 正数的补码和原码、反码一样,就是这个数的二进制值。 例如:25 00011001
负数的补码和原码、反码就不一样 原码:二进制值,最高位是符号位(正数的最高位是0,负数的最高位是1) -25 原码 10011001 反码 11100110 最高位不变,其余位取反,0->1,1->0 补码 11100111 反码 + 1 一个字节:-128~127 正数:0000 0001 ~ 0111 1111 1 ~ 127 零: 0000 0000 负数:1000 0001 ~ 1111 1111 -127 ~ -1 特殊值:1000 0000 -128 进制表示: 十进制的数字,就是和平时一样 二进制的数字,在数字前面加0B或0b 八进制的数字,在数字前面加0 十六进的数字,在数字前面加0x或0X
25的二进制是多少? 除2倒取余 二进制->八进制 从右边开始三位一组 二进制->十六进制 从右边开始四位一组 二进制->十进制 对应位数的值 * 2的n次方法,从右边开始n依次是0,1,2,.. 八进制->十进制 对应位数的值 * 8的n次方法,从右边开始n依次是0,1,2,.. 十六进制->十进制 对应位数的值 * 16的n次方法,从右边开始n依次是0,1,2,..
自动类型转换: long -->float 8个字节 4个字节 为什么说4个字节的float的存储范围比8个字节的long类型的大 小数在底层如何存储?也是用二进制存储 小数在底层:符号位 + 指数部分 + 尾数部分 和整数的存储不一样, 所以long虽然是8个字节,但是它的存储范围没有float的类型大。 double类型的尾数是52位,float是23位,所以double的精度比float大 因为小数部分转二进制可能是无限的,例如2.2,所以float和double是不精确,是浮点数
十进制的int 1234(4*8,4个字节 32位) --->>二进制的2个字节 给它转换成byte类型,那就会剩下8个了,截断高位的;
进制
对于整数:
二进制:0,1,满2进1.以0b或0B开头;
十进制:0-9,满10进1.
八进制:;0-7,满8进1,以数字0开头。
十六进制:0-9及A-F,满16进1,以0x或0X开头表示。此处A-F不区分大小写。如Ox21AF+1=OX21B0
最高位叫符号位;
正数符号位为0,负数的符号位为1; 在底层都是以补码的形式存的;
十进制转换二进制
4. 运算符(用以表示数据的运算、赋值和比较)
一、算术运算符
1、算术运算符 2、赋值运算符 3、比较(关系)运算符 4、逻辑运算符 5、条件运算符(三元运算) 6、位运算符 加:+ 减:- 乘:* 除:/ 如果除数和被除数都是整数,那么结果只保留整数部分 取余,取模:% 取模,正负号,只看被除数(被模数) 正号:+ 负号:- 字符串拼接:+ Java中对+这个运算符进行重载了,即+有两种意义,一个是加法,一个是字符串拼接 只要字符串参与+,结果一定是字符串,执行的一定是拼接。 自增:++ 自增1 ++在前,先自增,后load自增变量的值,然后再做别的 ++在后,先load自增变量的值,然后自增,然后再做别的 自减:-- 自减1
//测试算术运算符: + - * / % ++ -- 连接符+ class TestAri{ public static void main(String[] args) { //除: / int i = 12; int j = i/5; double d = i/5; double d1 = i/5.0; //int类型除以double类型 System.out.println(j); //2 System.out.println(d); //2.0 System.out.println(d1);//2.4 //取模: %:取余数,结果的符号取决于被模数 int i1 = 12 % 5; int i2 = -12 % 5; int i3 = 12 % (-5); int i4 = -12 % (-5); System.out.println(i1);//2 System.out.println(i2);//-2 System.out.println(i3);//2 System.out.println(i4);//-2 //前++:先自增1,后做运算; //后++:先做运算,后自增; int myInt1 = 10; int myInt2 = myInt1++; //后++ System.out.println(myInt1); //11 System.out.println(myInt2); //10 int myInt3 = 10; int myInt4 = ++myInt3; //前++ System.out.println(myInt3);//11 System.out.println(myInt4);//11 //前--:先自减1,后做运算; //后--:先做运算,后自减; } }
二、赋值运算符
最基本的赋值运算符:= 把=右边的(常量值、另一个变量的值、表达式的结果)赋值给左边的变量 注意:右边的(常量值、另一个变量的值、表达式的结果)类型要与左边的变量“一致”或“兼容” 扩展的赋值运算符:强调,扩展的赋值运算符中间不要加空格,即“+ =”错误的,"+=" += -= *= /= %= >>= .... (1)扩展运算符的右边是作为一个整体运算,然后再最后和左边的变量进行“+=,-=.....”的“+,-...”运算; 支持连续赋值。 (2)如果最后的结果的类型不符合左边的变量了,会发生“强制类型转换”
class Pratice1{ public static void main(String[] args){ short s = 3; //s = s + 2; //不兼容的类型: 从int转换到short可能会有损失 s += 2; System.out.println(s);//5 } }
三、比较运算符
比较运算符(又称为关系运算符) 大于:> 小于:< 大于等于:>= 小于等于:<= 不等于:!= 等于:== 比较运算符的表达式的结果只有两种,要么成立true,要么不成立false, 所以比较运算符的表达式通常用作条件。
比较运算符的结果都是boolean型,也就是要么是true,要么是false。
四、逻辑运算符
逻辑与:& 表示两个条件同时成立; 两边都为true时,整个结果才为true; true & true 结果为true true & false 结果为false false & true 结果为false false & false 结果为false 逻辑或:| 表示两个条件满足其一 两边只要有一个为true时,整个结果才为true; true | true 结果为true true | false 结果为true false | true 结果为true false | false 结果为false 短路与:&& 表示两个条件同时成立 两个都为true时,整个结果才为true;左边为false时,右边就不用计算了。 true && true 结果为true true && false 结果为false false && ? 结果为false false && ? 结果为false 短路与效率比逻辑与高,因为当&&左边是false时,右边的条件不看 短路或:|| 表示两个条件满足其一 只要有1个为true时,整个结果就是true;左边为true时,右边就不用看计算了。 true || ? 结果为true true || ? 结果为true false || true 结果为true false || false 结果为false 短路或效率比逻辑或高,因为当||左边是true时,右边的条件不看 开发中短路与和短路或用的更多 逻辑异或:^ 表示两个条件相反为true true ^ true 结果为false true ^ false 结果为true false ^ true 结果为true false ^ false 结果为false 逻辑非: ! 表示条件取反 !true 结果变成false !false 结果变成true //if(18 <= age < 35) //18 <= age,比较运算符的结果是boolean //(2)true < 35 或 false < 35 ,没法比较
左右两端都是布尔类型的
//逻辑运算符 : & && | || ! ^ class TestLogic{ public static void main(String[] args) { boolean a = true; boolean b = false; System.out.println(a & b); //false System.out.println(a && b);//false System.out.println(a | b); //true System.out.println(a || b); //true System.out.println(a & !b); //true System.out.println(a^b); //true //& 与 &&的区别: &不管左边是true还是false,右端都会进行运算; // &&当左端为false时,右端不再进行运算; // 以后使用时,建议使用&& int i1 = 10; if(b & (i1++) > 0){ System.out.println("今天天气好暖和啊"); }else{ System.out.println("难得没有雾霾"); } System.out.println(i1);//11 int i2 =10; if(b && (i2++) > 0){ System.out.println("今天天气好暖和啊"); }else{ System.out.println("难得没有雾霾"); } System.out.println(i2);//10 //| 与 ||的区别: | 当左端为true时,右端照样做运算; // ||当左端为false时,右端不再进行运算; // 以后使用时,建议使用|| int i3 = 10; if(a | (i3++) > 0){ System.out.println("今天天气好暖和啊"); }else{ System.out.println("难得没有雾霾"); } System.out.println(i3);//11 int i4 =10; if(a || (i4++) > 0){ System.out.println("今天天气好暖和啊"); }else{ System.out.println("难得没有雾霾"); } System.out.println(i4);//10 } }
五、位运算符
位运算是直接对二进制进行运算; 注意没有<<<
左右两端都是数值类型的,注意与逻辑& 、| 、^ 的区别
右移,就看你原来的那个数最高位是0还是1,是0的拿0补,是1的拿1补;
位运算符 (1)左移:<< 快速算:左移几位,就相当于乘以2的几次方 本质上: 以2为例,2是int,4个字节,32位 补码:0000 0000 0000 0000 0000 0000 0000 0010 2<<4 0000 0000 0000 0000 0000 0000 0010 0000 以-2为例,-2是int,4个字节,32位; 左移补码补0 原码:1000 0000 0000 0000 0000 0000 0000 0010 反码:1111 1111 1111 1111 1111 1111 1111 1101 (符号位即最高位不变,其他取相反数) 补码:1111 1111 1111 1111 1111 1111 1111 1110 (补码就是 -->> 反码 + 1) -2<<4 1111 1111 1111 1111 1111 1111 1110 0000 结果仍然是补码 反码:1111 1111 1111 1111 1111 1111 1101 1111 原码:1000 0000 0000 0000 0000 0000 0010 0000 (2)右移:>> 快速算:右移几位,就相当于除以2的几次方(对于负数有点不太对) 40的补码:0000 0000 0000 0000 0000 0000 0010 1000 40>>4:0000 0000 0000 0000 0000 0000 0000 0010 左边补什么,看最高位 -40的补码: 原码:1000 0000 0000 0000 0000 0000 0010 1000 反码:1111 1111 1111 1111 1111 1111 1101 0111 补码:1111 1111 1111 1111 1111 1111 1101 1000 -40>>4:1111 1111 1111 1111 1111 1111 1111 1101 反码:1111 1111 1111 1111 1111 1111 1111 1100 原码:1000 0000 0000 0000 0000 0000 0000 0011 -3 (3)无符号右移:>>> 和右移的区别就是,无论最高位是什么,左边缺几位,补几个0 -40的补码: 原码:1000 0000 0000 0000 0000 0000 0010 1000 反码:1111 1111 1111 1111 1111 1111 1101 0111 补码:1111 1111 1111 1111 1111 1111 1101 1000 -40>>>4:0000 1111 1111 1111 1111 1111 1111 1101 (4)按位与:& 对应二进制位,按位与 1 & 1 结果为1 1 & 0 结果为0 0 & 1 结果为0 0 & 0 结果为0 (5)按位或:| 对应二进制位,按位或 1 | 1 结果为1 1 | 0 结果为1 0 | 1 结果为1 0 | 0 结果为0 (6)按位异或:^ 对应二进制位,按位或 一个整数与另一个整数异或两遍,就是它本身 1 ^ 1 结果为0 1 ^ 0 结果为1 0 ^ 1 结果为1 0 ^ 0 结果为0
如:a = a ^ b
b = a ^ b #b = a ^ b ^ b
a = a ^ b
===>> 这时候就把a,b两个的值交换了。(适用于整数)
(7)按位取反:~ 每一位取反,1变0,0变1 */ class TestBit{ public static void main(String[] args){ System.out.println(2 << 4);//2 * 2的4次方 ==>> 32 = 2 * 2^4 System.out.println(-2 << 4);//-32 System.out.println(40 >> 4);//2 40 / 2的4次方 = 40/16 = 2 System.out.println(-40 >> 4);//-3 -40 / 2的4次方 = -40 / 16 = -3 System.out.println(-40 >>> 4);//268435453 System.out.println(1 & 2);//前面都是0 01 & 前面都是0 10 -->> 0.. 00 输出打印0 System.out.println(1 & 3);//前面都是0 01 & 前面都是0 11 -->> 0.. 01 输出打印1 System.out.println(1 | 2);//前面都是0 01 | 前面都是0 10 -->> 0.. 11 输出打印3 System.out.println(1 | 3);//前面都是0 01 | 前面都是0 11 -->> 0.. 11 输出打印3 System.out.println(1 ^ 2);//前面都是0 01 ^ 前面都是0 10 -->> 0.. 11 输出打印3 System.out.println(1 ^ 3);//前面都是0 01 ^ 前面都是0 11 -->> 0.. 10 输出打印2 System.out.println(~1); //0000 0000 0000 0000 0000 0000 0000 0001 //1111 1111 1111 1111 1111 1111 1111 1110 补码 //1111 1111 1111 1111 1111 1111 1111 1101 //1000 0000 0000 0000 0000 0000 0000 0010 输出打印为 -2 } }
class TestExer1 { public static void main(String[] args) { int m = 12; int n = 5; System.out.println("m:" + m + "n:" + n); //方法一:提供一个临时变量; //int temp = m; // m = n; // n = temp; //System.out.println("m:" + m + "n:" + n); //方法二:当m和n较大时,有可能出现精度损失; //m = m + n;// m = 12 + 5; //n = m - n;// m = 17 - 5; //m = m - n;// m = 17 - 12; //System.out.println("m:" + m + "n:" + n); //方法三:优点:没有上面两种方法的缺点 m = m ^ n; n = m ^ n; //(m ^ n) ^ n == m m = m ^ n; //(m ^ n) ^ m == n System.out.println("m:" + m + "n:" + n); //60 手动的方式,从控制台输出60的十六进制. int i = 60; //操作 System.out.prinln();//3c } }
//60 手动的方式,从控制台输出60的十六进制. int i = 60; //自动调用Integer类现成的方法 String binary = Integer.toBinaryString(i); //变成二进制 System.out.println(binary); //111100 String hex = Integer.toHexString(i); System.out.println(hex);//3c /* char c = 'a'; char c1 = (char)(c + 2); System.out.println(c1); //c */ int j = i & 15; //获取到i的最低4位对应的值。 String k1 = (j <= 9)?j + "" : (char)(j - 10 + 'a') + ""; //System.out.println(k1);//c i = i >> 4; int z = i & 15; String k2 = (z <= 9)? z + "" : (char)(z - 10 + 'a') + ""; System.out.println(k2 + k1);
六、条件运算符(唯一的三元运算符)
一元运算符:正号,负号,++,--,逻辑非! 一元运算符是只要一个操作数 +m,!true, i++ 二元运算符:加法、减法... 比较运算符 二元运算符有两个操作数: a+b,a-b ,a > b 三元运算符:三个操作数 语法格式: 条件表达式 ? 结果表达式1 : 结果表达式2 运算规则: 如果条件表达式成立true,整个三元运算符,就取结果表达式1的值,否则就取结果表达式2的值
int max = a>=b ? a : b;
int big = (m>=n ? m : n) >= l ? (m>=n ? m : n) : l;
/* 三元运算符:(表达条件式) ? 表达式1 : 表达式2; 要求:表达式1与表达式2为同种数据类型。 既然是运算符,就一定会有运算结果,结果的数据类型与表达式1,2的类型一致。 三元运算符在一定程度上可以与if-else互换(三元运算符一定可以转换为if-else,反之不成立。) */ class TestSanYuan{ public static void main(String[] args) { int i = 20; int j = 20; //此时max记录了i与j的较大值 int max = (i > j)?i : j; //String str = (i > j) ? "i大" : "j大"; String str = (i > j)? "i大" : (i == j)? "相等" : "j大"; //String str1 = (i > j)? i : "j大"; System.out.println(max); System.out.println(str); //互换 if(i > j){ System.out.println("较大值为:" + i); }else{ System.out.println("较大值为:" + j); } //练习:如何使用三元运算符,输出三个数中的较大值 int m = 12; int n = 23; int k = -9; int max1 = (m > n)? m : n; int max2 = (max1 > k)? max1 : k; System.out.println(max2); } }