1.Java跨平台的原理:
1)编译之后会生成与平台无关的字节码文件
2)得依赖不同平台的虚拟机(JVM)
JVM是不跨平台的
编译工具:javac
启动JVM工具:Java
JRE(Java Runtime Environment):Java运行环境,如果要运行Java程序,就需要JRE的支持,JRE里边包含JVM
JDK(Java Development Kit):Java开发工具,包含开发Java的所有工具,如javac和java等,JDK里包含JRE
Java虚拟机(Java Virtual Machine),简称JVM,它是运行所有Java程序的虚拟计算机,好比是街机游戏的模拟器。
JVM是Java语言的运行环境,也是Java最具吸引力的特性之一。JVM用于读取并处理编译过的与平台无关的字节码(class)文件,从而实现Java的可移植性。但是值得注意的是Java虚拟机是不跨平台的,也就是说在Win下得安装Win版本的JVM,在Linux下得安装Linux版本的JVM
JVM是Java程序的解释和执行器
2.Java安装后各个文件夹的含义
(1)bin:存放了Java的操作工具,比如编译工具javac,启动JVM的java等
(2)db:存放了Java测试的数据库derby,企业不用
(3)include:存储C++头文件
(4)jre:Java的运行环境,里面有JVM
(5)lib:Java运行和依赖的核心库
(6)src.zip:Java的源代码
3.安装jre运行java程序
(1)jre-8u121-macosx-x64.dmg(下载安装,在系统偏好设置的面板上)
(2)创建一个空文本,命名为.java文件(比如123.java 文件中有一个名为Hello的类,.java是后缀名或者拓展名)
(3)在终端找到文件路径执行javac 123.java,对文件进行编译,编译成功后此时路径下会生成一个Hello.class的字节码文件
(4)启动JVM,并加载Hello.class这份字节码,并解释执行(执行命令 java Hello),注意不要带后缀.class,就会执行字节码文件中的代码
(5)每次修改代码都需要进行编译
代码解释
// Java程序的开始,表示定义一个公共的类,类的名字是Hello,编译后会生成一个和该名字一样的class文件
public class Hello {
// 主方法,Java程序的入口,执行Java命令后,程序自动执行主方法代码
public static void main(String[] args) {
// 功能执行代码,表示打印一个文本信息“Hello World”,最后要以分号结束,表示语句结束
System.out.println("Hello World");
}
}
4.Java编译和运行机制
源文件(.java) ->编译-> 字节码文件(.class)->输出-> Hello World
Java语言编译型语言
5.CLASSPATH(一般不用配这个环境变量)一般默认在当前目录下
环境变量:指在操作系统中用来指定操作系统运行环境的一些参数
JAVA_HOME: 指JDK的安装根目录,如D:\OpenSource\jdk1.8.0
PATH: 指Java开发工具的位置,如D:\OpenSource\jdk1.8.0\bin
CLASSPATH: 指JVM在运行时去哪一个目录路径加载字节码文件
如果在当前路径下希望把字节码文件统一到一个文件夹中,可以新建一个文件夹命名为classes 编译的时候使用命令javac -d classes 123.java 就可以将123.java的编译文件放在classes的文件夹下,解释字节码文件的命令此时换成java -classpath classes Hello就可以得到程序执行的结果
6.Java基本语法
1)Java语言严格区分大小写,好比main和Main是完全两个不同的概念。
2)一个Java源文件里可以定义多个Java类,但其中最多只有一个类被定义成public类。若源文件中包含public类,源文件必须和该public类同名
3)一个源文件中包含N个Java类时,成功编译后会生成N份字节码文件,即每个类都会生成一份单独的class文件,且字节码文件名和其对应的类名相同
4)若一个类必须运行,则必须拥有main方法,因为main方法是程序的入口
编程建议:
一个Java源文件只定义一个类,不同的类使用不同的源文件定义;
将每个源文件中单独定义的类定义成public的;
保持Java源文件的主文件名与源文件中的类名一致;
7.标识符
在写代码的时候为了增强代码的阅读性会自定义很多名字,比如类名,方法名,变量名等.这些自定义的名称,成为标识符
标识符命名规则:
(1)由字母、数字、下划线、$组成,但不能以数字开头(注:此处的字母可以是中文、日文等,类名首字母大写)
(2)大小写敏感
(3)不能使用Java的关键字和保留字
(4)不用Java API里的类名作为自己的类名
8.变量分类-作用域-使用规则:
变量的分类:
随着变量定义在类中的位置的不同,故把变量分为两类:
(1)成员变量:直接定义在类里的变量,又称为全局变量或字段.
(2)局部变量:变量除了成员变量以外,其他就是局部变量.根据定义位置不同有3种表现形式:方法形参,方法内变量,代码块变量
变量的作用域:
根据变量的存在范围,只有在这个范围内,程序代码才能访问它.当一个变量被定义时,他的作用域就被确定了
作用域是定义开始到定义所在的花括号结束;
变量的使用规则:
(1)变量必须先声明,并且初始化后才能使用;
(2)声明变量必须有数据类型
(3)同一作用域内变量名不能重复定义
先声明赋值后使用,并且可重复使用
//变量分类-作用域-使用规则
public class VarDemo2{
//成员变量,字段(不叫属性)
static int age=17;
public static void main(String[] args){
/*
变量的分类:
变量依据定义的位置的不同,分为两大类:
1.成员变量/字段(Field):直接定义在类的{}中的变量(在方法外)
--报错:无法从静态上下文中引用非静态变量
2.局部变量(定义在方法中的变量)
变量除了成员变量,就是局部变量.
3.变量的作用域:可以起作用的领域.
1.成员变量:在所定义的类中起作用
2.局部变量:从定义的那个地方开始,到紧跟着结束的"}"之间
*/
int age=18; // 局部变量
System.out.println(age);/*输出18,当成员变量和局部变量同名时,编译不会出错,得到的结果采取就近原则*/
}
}
9.表达式(expression):是由数字、运算符、数字分组符号(括号)、变量、常量等以能求得结果的有意义排列的组合。
用运算符号连接的变量/常量可称为表达式.那么也就是说表达式是由常量、变量、运算符、括号组成能求得之的有意义结果的语句。
如:
a+b
3.14+a
(x+y)*z+100
表达式中操作数进行运算得到的最终结果就是表达式的结果
表达式的运算顺序(大多和数学一样,参照后面的运算符操作优先级);
a + 110 -->表达式
操作数 运算符 操作数
10.在JAVA中数据类型整体上分为两大类:
1):基本数据类型/原生数据类型:共8个
1>:数值型
1/:整数类型: byte short int long;(不同正数类型在内存中占用空间大小是不一样的,整数常量默认是int类型)
2/:小数类型:float double;
2>:字符型:char (字符:字母/符号)
3>:布尔型:boolean,表示对错:ture false;
2):引用数据类型/对象数据类型:
类 / 接口 / 数组
11.小数的默认常量为double类型,若要声明小数常量卫float类型,就在后面加F或f
float表示单精度
double表示双精度
但是两者均不能表示精确的小数,那么在精度要求很高的系统如银行系统中,就需要使用BigDecimal类型,它表示任意精度的数据
Java的浮点类型常量有两种表现形式:
(1)十进制形式:例如:3.14,168.0,.618
(2)科学计数法形式:例如:3.14e2,3.14E2,1000E-2
科学计数法表达式返回的结果是Double类型的
默认情况下,一个浮点类型的字面量默认是double类型,若要声明一个常量为float类型,则需要在常量后加上f或者F,double常量后面的D或者d可省略。注意:Java只有浮点型的变量才可以接受科学计算数的结果
12.字符类型:字符、字母和符号
char类型:表示16位的无符号整数或者Unicode字符,Java对字符占用两个字节,可以表示一个汉字
什么是编码?
计算机只能表示0和1两个数,于是规定使用一个数字去表示一个特定的字符,比如a使用97表示 char前256个字符和ASICC(美国信息交互标准编码)码中的字符重复
13.基本数据类型的转换
在8大基本数据类型(byte-1字节,short-2字节,int-4字节,long-8字节,double,float,char-2字节,boolean),boolean不属于数值类型,不参与转换
字节数 byte < short(=char) < int < long < float < double (一般的byte short char不参与转换 char虽然也是2字节但是不包含负数跟short比起来数量少,因此short和char不能相互转换)
转换规则其实就是各自数据类型的空间大小,把不同的数据类型看成是不同容量的容器
自动类型转换,也称为“隐式类型转换”(从小到大)
强制类型转换(从大到小 显式类型转换):当把大范围类型的数值赋给另一个小范围变量时,此时系统不能自动完成转换,需要加上强制转换符,但这样的操作可能造成数据精度的降低或溢出,所以使用时要格外注意
byte b2 = 125; 把一个int类型常量赋值给byte类型变量,编译时,发现125在byte的范围之内,底层就会转换成byte类型的但是如果设置成byte b2 = 128; 则就会报错了
14.表达式类型的自动提升
当一个算数表达式中包含多个基本数据类型(boolean除外)的值时,整个算数表达式的数据类型将在数据运算时出现类型自动提升,其规则是:所有的byte,short,char类型自动提升到int类型 整个表达式的最终结果类型提升到表达式中类型最高的类型
String和任意数据使用,连接起来就是String(字符串)
double d2 = 123 + 1.1F + 99L + 3.14;
System.out.println(d2); // 输出226.2400061035156
System.out.println('A' + 1); // 输出66
byte b4 = 25;
// b4 = b4 + 3; // 表达式运算后已经提升到int类型了,在赋值给byte类型,编译会报错
// 为了避免这种情况 将会用到赋值运算符
b4 += 3; // 这里就体现出了+=赋值运算符的好处了
System.out.println(b4); // 28
b4 += 3 等价于 b4 = (byte)(b4 + 3)
查看第16点笔记
15.算术运算符
取模(求余数):模数的符号忽略不计,结果的正负取决于被模数
注意:无穷大和NaN都属于double浮点类型,但是所有的正无穷大都是相等的,所有的负无穷大也是相等的,NaN永远不相等,也不等于自己
public class ArithmeticOperatorsDemo {
public static void main(String[] args) {
// 操作数字
System.out.println(10 + 2); // 12
System.out.println(10 - 2); // 8
System.out.println(10 * 2); // 20
System.out.println(10 / 2); // 5
System.out.println("----------------------");
// 操作字符
System.out.println('A' + 'B'); // 131
// 操作字符串
System.out.println("AAA" + "BBB"); // AAABBB
System.out.println("----------------------");
System.out.println(10 / 3); // 3
System.out.println(9876 / 1000 * 1000); // 9000
System.out.println("----------------------");
// System.out.println(100 / 0); // 报错 by zero
System.out.println(100.0 / 0); // Infinity正无穷大
double d1 = 100.0 / 0;
double d2 = 200.0 / 0;
System.out.println("所有的正无穷大都相等吗?");
System.out.println(d1 == d2); // true
double d3 = -100.0 / 0;
double d4 = -200.0 / 0;
System.out.println("所有的负无穷大都相等吗?");
System.out.println(d3 == d4); // true
System.out.println("正无穷大和负无穷大相等吗?");
System.out.println(d1 == d3); // false
System.out.println(100 / 0.0); // Infinity正无穷大
System.out.println(-100 / 0.0); // -Infinity负无穷大
System.out.println(0.0 / 0.0); // NaN Not a Number 自己都不等于自己
double d5 = 0.0 / 0.0;
System.out.println(d5 == d5); // false
// 取模(求余数):模数的符号忽略不计,结果的正负取决于被模数
System.out.println(10 % 3); // 1
// 自增 ++
/*
* ++前置情况
* ++a
* 表示a变量自身先加1,再运算
* ++后置情况
* a++
* 表示a变量自身先加1,把递增1之前的原始值拿去做运算
* */
// --道理一样
System.out.println("---------------");
int a1 = 5;
int b1 = ++a1;
System.out.println("a1 = " + a1 + " b1 = " + b1); // a1 = 6 b1 = 6
System.out.println("---------------");
int a2 = 5;
int b2 = a2++;
System.out.println("a2 = " + a2 + " b2 = " + b2); // a2 = 6 b2 = 5
}
}
16.赋值运算符
public class AssigningOperatorsDemo {
public static void main(String[] args) {
short a = 10;
//a = a + 5; // 编译报错
a += 5;
// a += 5 等价于 a = (short)(a + 5);
System.out.println(a); // 15
}
}
17.比较运算符
==, !=, >, <, >=, <=, instanceof(检查是否是类的对象) "Hello" istanceof String true
比较运算符用于比较两个常量或者变量之间的关系,比较运算的结果都是boolean类型
18.三元运算符
三元运算符表示有三个元素参与的表达式,又称为三目运算符,其语义表示为if-else。
语法格式为:X ? Y : Z 其中X为boolean类型表达式,先计算X的值,若X计算结果为true,则整个三目运算表达式的结果是Y,否则就是Z。三目运算符结果的类型是由Y和Z决定的
19.逻辑运算符
运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
& | AND(位与) | false & true | false |
丨 | OR(或) | false 丨 true | true |
^ | XOR(异或) | false ^ true | true |
! | NOT(非) | !true | false |
&& | AND(短路) | false && true | false |
丨丨 | OR(短路) | false 丨丨 true | true |
语法格式为:boolean result = 表达式A 逻辑运算符 表达式B
&:表示并且,当操作数A和B都为true结果才为true,否则结果result是false
&&:和&结果相同,具有短路效果,如果左边操作数A是false,result一定是false,且不运行B的运算
|:表示或者,当操作数A和B都为false结果才为false,只要有A或者B为true,结果result是true
||:和|结果相同,具有短路效果,如果左边操作数A是true,result一定是true,且不运行B的运算
^:判断A和B是否相同,不同则为true,相同则为false
!:取反,!true结果是false,!false结果是true
20.位运算符
运算符 | 描述 |
---|---|
& | 按位与 |
丨 | 按位或 |
^ | 异或(相同为0,不同为1) |
~ | 取反 |
<< | 左移位 |
>> | 右移位 |
>>> | 无符号右移位 |
&:参与运算的两个数,若相应位数的值都为1,则该位结果值是1,否则是0.
|:参与运算的两个数相应位中只要有一个1,结果就是1.
^:参与运算的两个数相应位相同则结果为0,否则为1.
~:表示把两个二进制位的“1”换成“0”,把“0”换成1.
<<:将操作数的二进制码整体左移指定位数,左移之后的空位用“0”来补充.
:将操作数的二进制码整体右移指定位数,右移之后的空位用“符号位”来补充:
若是正数用“0”来补充
若是负数用“1”来补充(操作负数:取反,求补):将操作数的二进制码整体右移指定位数,右移之后的空位用“0”来补充:
二进制数a | 二进制数b | 与(&) | 或(丨) | 异或(^) |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 1 | 1 |
0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
boolean的true和false,在底层使用一位的1和0表示
public class BitOperatorsDemo {
public static void main(String[] args) {
System.out.println(3 & 5);
System.out.println(3 | 5);
System.out.println(3 ^ 5);
System.out.println(~3);
System.out.println(2 << 3);
System.out.println(16 >> 3);
System.out.println(-16 >> 3);
// 交换两个数
int a = 10;
int b = 20;
System.out.println("a = " + a + " b = " + b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println("a = " + a + " b = " + b);
}
}