java版本
- javaSE:java platform standard edition(基础版)
- javaEE:企业版,包含一系列技术jsp Servlet jdbc xml,开发框架:Struts2 sprint
- javaMe:微型版,手机嵌入式看法
安装java
jdk :为方便找寻安装位置,安装在自定义文件夹下可能会好些
jdk:包括了jre,java工具,java的基础API
jre: jvm+JAVA的核心类库
环境变量:
win10:计算机 -> 属性 -> 高级系统设置 -> 环境变量(N)
JAVA_HOME:java安装目录,比如:C:\Users\java(这里是自定义目录)
PATH:不同以英文分号分隔,位于JAVA_HOME下的bin目录:%JAVA_HOME%/bin
java虚拟机(JVM)运行过程
Java在执行的时候,需要需要用到编译器和解释器
- 编译器将.java文件编译成.class文件(scala也是编译成class字节码文件)
- 运行的时候,通过类加载器加载.class文件,通过字节码校验器对.class文件进行校验。
解释器对于class文件进行解释,执行。这个过程中会有jit技术(缓存);
idea创建java项目
File -> New -> Project -> (配置SDK)Next -> Next -> (输入项目名称)Finish
java文件一般放在src目录下;
/** [这里是文档注释,idea输入/**+回车]
* @author linglingqi
* @version 1.0
*/
package day1;
import java.util.Scanner;
// 不同于python、scala,java每行使用英文';'结尾,缩进只是强化代码可读性;
public class HelloWorld { // 类名称必须与文件名称保持一致,scala可不同
public static void main(String[] args){
// 输出[单行注释]
System.out.print("hello world");
System.out.println("print");
// 输入
// (1) 导入Scanner
// (2) 创建对象
Scanner sc = new Scanner(System.in);
String name = sc.next(); // 输入接收的是字符串
// sc.nextInt() Int类型
// sc.nextFloat 浮点类型
System.out.println("您输入的名字是:" + name);
}
}
静态语言|动态语言、强类型与弱类型
java:强类型静态语言
静态语言:声明一个变量时,必须指定变量类型,变量值修改,只能修改为同类型其他值;
动态语言:不需要指定类型,修改这个变量可以修改为其他类型,比如python;
强类型语言:定义了数据类型,除非经历转化,不然一直处于这一种类型;
注释三种方式
- 单行注释:双斜杠//标识到行尾;
- 多行注释:/* 换行中间多行注释 */结尾
- 文档注释:功能性注释一般放在文件的最开头,标注创建日期、作者、功能、方法参数;
变量
变量的声明
类型 变量名 [= 变量值]
变量在声明之后,可以进行初始化,也可以不进行初始化;
一次性声明多个变量:变量的类型需一致,建议一次性不要声明太多,可读性较差;
变量值修改,值类型需与声明类型一致;
必须先声明后使用;
int num = 100; // 变量声明
int num2; // 不初始化
num = 200; // 变量修改,值类型跟变量声明类型需一致;
int a,b=2,c=3,d;
变量的内存结构
不同类型的变量存储位置不同;
java中的存储数据的区域:寄存器/栈、堆、静态存储、常量存储区、非随机存储器…
- 栈:存储速度比较快,缺点在栈中的数据大小和声明周期是有明确规定;
- 堆:动态分配内存,存储速度比较慢,声明周期长;
基本数据类型-局部变量:存储在栈中;
引用类型:栈中存储引用,堆中存储真正对象;
变量的分类与作用域
从范围角度:成员变量与局部变量
成员变量:声明在类中,整个类中有效;
局部变量:声明在语句块{}中,在当前语句块中有效;
相同作用域下,不能声明两个同名的变量;
变量赋值给变量
变量不能直接赋值给另外一个变量,只能将自己的对象(值)赋值(复制)给另外一个变量;
// java
int a = 100
int b = a
// a和b指向两块不同的内存地址
在python中,指向同一个地址
# python
a = 100
b = a
print(id(a) == id(b)) # 两个id是一个
常量
特殊的变量:不可以改变的量;
普通常量:
变量命名全使用大写;
使用static final float 修饰(不可修改);
String NAME = "Alice" // 这样定义常量,实际还是可以修改的;
static final AGE int = 10 // 使用final修饰,变量不可修改;
特殊常量
null、true、false
null:代表没有任何有效对象,引用类型;
数据类型
基本数据类型:
java内置类型:可以直接使用的类型;
引用类型:class定义声明的对象类型;
基本的数据类型:
默认的小数都是double类型;
浮点类型都是不精确的;
基本数据类型:(8中);引用类型:(String)
如果是局部变量,变量名字作为数据存储区域的名,变量值直接存储在数据区域中,全部存储在栈中;
boolean:true false 占位(不同的厂商决定,占位最少)
byte:字节8个数据位 有符号;
char:字节16个数据位 无符号
short:16 有符号 短整型
int:32 有符号 整型
long:64 有符号 长整型
float:32 有符号
double:64 有符号
float f = 10.f // 默认小数是double类型,需加f后缀表示float类型,跟scala是一样的;
// 浮点数支持科学计数法
float f1 = 2.1e10f
// 浮点类型都是不精确的,只能做近似存储;
System.out.println(10.0/3.0)
基本类型的转化
在java中,布尔类型无法与其他类型互相转化;
自动转化:
有低类型赋值给高类型,可以直接做隐式转化
高低:占用的数据位数
特殊:float double 高于其他类型
排序:byte < short < int < long < float < double
char和short、byte不能直接进行隐式转化
byte b = 120;
int i = b; // 低数据类型向高类型,自动发生隐式转化;
强制转化:
从高类型向低类型转化,需要强制转化;
语法格式:A x = (A) y 将y强制转化成A类型;
强制转化会损失精度;
char和short、byte需要强制转化;
float与double转化:浮点型默认是double类型;
整数类型默认是int32类型;
int i = 130;
byte b = (byte)i; // 会截断8位,-126
char c = 'A';
byte b1 = (byte)c; // 65,截取byte位数
//float与double转化
float f = 0.1f; // 损失进度,或者也可以float f = (float)0.1
//
int i = 32;
long l = 32; // 默认
类型的提升:
对于基本类型的数据之间进行运算,结果获取的类型;
相同类型的变量、常数进行运算,结果仍然是原类型;
不同类型的变量、常数进行运算,结果与参与运算中高类型保持一致;
byte、char、short运算结果会提升至int;
byte b = 1;
short s = 2;
int i = b + s; // 只能使用int类型
int i1 = 100;
int i2 = 200;
int i3 = i1 + i2; // 相同类型,结果同类型保持一致
long l1 = 10;
long l2 = l1 + i1; // 不同类型结果为高类型long;
System.out.println(i1/i2); // 结果凡是是0,而不是0.5,返回是int类型在,自动截断整数;
小数类型的二进制规则:
小数部分 * 2 = 结果,取整数部分,float精度32位
0.1 * 2 = 0.2 整数0
0.2 * 2 = 0.4 整数0
0.4 * 2 = 0.8 整数0
0.8 * 2 = 1.6 整数1
0.6 * 2 = 1.2 整数1
0.2 * 2 = 0.4 整数0
…总长度32位,不精确;
浮点类型使用注意事项
- 避免数量级相差很大的浮点值之间进行计算;
- 避免使用浮点数进行比较;
《Effective Java》float和double类型适合做科学计算或者工程计算不用十分精确的适合
如果需要非常精确的数据,使用java.math.BigDecimal
import java.math.BigDecimal;
public class Calculate{
public static void main(String[] args){
float f1 = 3e15f;
float f2 = 1.0f;
System.out.println(f1 + f2); // f2基本被忽略
double d1 = 0.1;
double d2 = 0.2;
System.out.println(d1 + d2 == 0.3) ; // 判断值是否相等
BigDecimal bd1 = new BigDecimal(0.1); // 显示浮点类型的原型
System.out.println(bd1);
// 解决,使用字符串传入
BigDecimal bd2 = new BigDecimal("0.1"); // 0.1
BigDecimal bd3 = new BigDecimal("0.5"); // 0.5
BigDecimal bd4 = new BigDecimal("0.6"); // 0.6
System.out.println(bd2.add(bd3) == 0.6); // 不相等,0.6是浮点不精确的;
System.out.println(bd2.add(bd3).equal(bd4)); // 相等,true
}
}
字节与字符
- 字节byte 类型 支持8个数据位,-128-127
应用场合:
- 从网络传输文件的时候,数据流、二进制的文件,比如存储照片byte[]
- 字符集出现乱码的时候
- 字符char:使用无符号16位,0-2^16 65536,变量必须使用单引号’'括起来;
unicode字符集:UCS-2:16位(char:常用字符集);UCS-4:32位
abc ascii码(键盘) gb2312(中国) gbk(包含少数名族)
char C = 'A'
char c1 = 65 // 也可以使用ascii码
char c2 = '/u5927' // 也可以使用unicode字符集的编码
- 转义序列:表示特殊的字符
换行:\n
回车:\r
制表符:\t
表示斜杠\本身:\
整数类型的四个进制
二进制:使用0b或者0B前缀
八进制:使用0前缀
十进制:无需前缀
十六进制:使用0x或者0X前缀(0-9,10-15使用a-f或者A-F)
int i2 = 0b11 // 二进制:3
int i8 = 011 // 八进制:9
int i10 = 11 // 十进制:11
int i16 = 0x1a // 十六进制:26
原码、反码、补码
计算机所有的数据都是以补码形式存储;
- 正数:原码、反码、补码相同,二进制码;
- 负数:
- 原码:正数的二进制码,符号位取1,最高位(4、8、16、32、64);
- 反码:符号位不变,其余取反;
- 补码:反码+1;
从原码变成补码:取反码 -> 反码 + 1
从补码变原码:取反码 -> 反码 + 1(跟-1,取反码结果是一样的;)
四位:
补码:3 + -4 = 0011(二进制) + 1100(二进制) = 1111(-1的补码)
-1,正二进制:0001,负原码:1001,负反码:1110,负补码:1111
十进制 | 正数二进制 | 负数原码 | 负数反码 | 负数补码 |
---|---|---|---|---|
0 | 0000 | 1000 | 1111 | 0000 |
1 | 0001 | 1001 | 1110 | 1111 |
2 | 0010 | 1010 | 1101 | 1110 |
3 | 0011 | 1011 | 1100 | 1101 |
4 | 0100 | 1100 | 1011 | 1100 |
5 | 0101 | 1101 | 1010 | 1011 |
6 | 0110 | 1110 | 1001 | 1010 |
7 | 0111 | 1111 | 1000 | 1001 |
8 | 1000 | - | - | - |
6 + (-7)计算机如何运算?
步骤:
- 估计结果,操作数和结果再-7-7之间,可以用4位模拟机;
- 将所有操作转化成补码形式计算;
6 + (-7) = 0110 + 1001 = 1111
待更新…