Java开发环境搭建
Java语言特性
在Java语言中真正操作内存的是:JVM(Java虚拟机)
所有的Java程序都是运行在Java虚拟机当中的。
而Java虚拟机执行过程中再去操作内存。
Java语言底层是C++,所以JVM是用C++语言写好的一个虚拟的计算机。Java程序实际上没有直接和操作系统打交道。
术语
JavaSE:标准版;JavaEE:企业版;JavaME:微型版。
JDK:Java开发工具箱;JRE:Java运行环境。
Java的加载与执行原理
java HelloWorld的执行过程:
- 先启动JVM;
- JVM启动后,JVM会去启动类加载器,类加载器负责去硬盘上找“类”对应的“字节码”文件(HelloWorld.class);
- 类加载器如果在硬盘上找不到对应的字节码文件——错误:找不到或无法加载主类;类加载器如果找到了,类加载器会将字节码文件装载到JVM中,JVM启动解释器将字节码解释为二进制码,操作系统执行二进制码和硬件交互。
环境变量
安装Tomcat服务器需要配置JAVA_HOME环境变量。
让类加载器去指定的路径下加载字节码文件:设置一个环境变量,叫做classpath,classpath环境变量是java特有的。配置了classpath之后类加载器只会去配置的路径下去找不会再去当前路径下找。
注释
/**
*javadoc注释:这里的注释信息可以自动被javadoc.exe命令解析提取并生成到帮助文档中
*/
例如:
public class T{
/**
* 这是一个程序的入口
* @param args是main方法的参数
*/
public static void main(String[] args){
}
}
生成javadoc文档:
javadoc -d javaapi T.java
把javadoc放入javaapi文件夹。
接收键盘输入
public class HelloWorld {
public static void main(String[] args) {
java.util.Scanner s=new java.util.Scanner(System.in);
int a=s.nextInt();
System.out.println(a);
}
}
import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
int a=s.nextInt();
System.out.println(a);
}
}
类
在java中任何有效的代码必须写到类当中。
class A{
}
class B{
}
class C{
}
//编译通过
一个java源代码文件中有多个类,编译后有多个class文件。
public的类不是必须的。
class A{
}
public class B{
}
class C{
}
//编译报错
public的类可以没有,但如果有的话,public修饰的类名必须和源文件名保持一致。因此一个java文件里面public的类只能有一个。
class T1{
public static void main(String[] args){
System.out.println("T1...");
}
}
class T2{
public static void main(String[] args){
System.out.println("T2...");
}
}
class T3{
public static void main(String[] args){
System.out.println("T3...");
}
}
//编译通过
想从哪个入口进去,就加载哪个类。例如:
java T1
java T2
java T3
变量
字面量
在Java中数据被称为字面量。例如10、1.23、true、’a’、”abc”,分别为整数型字面量、浮点型字面量、布尔型字面量、字符型字面量、字符串型字面量。
只有字面量内存是无法重复利用的,使用变量以后内存空间就得到了重复利用。
变量
变量是内存中存储数据的最基本的单元。
Java变量必须先声明再赋值才能访问(没有值相当于空间没有开辟)。
局部变量只在方法体中有效,方法体执行结束该变量的内存就释放了。
数据类型
类型 | 占用字节数量 | 取值范围 |
---|---|---|
byte | 1 | [-128,127] |
short | 2 | [-32768,32767] |
int | 4 | [-2147483648,2147483647] |
long | 8 | |
float | 4 | |
double | 8 | |
boolean | 1 | |
char | 2 | [0,65535] |
字符型
字符编码
字符编码规定了一系列文字对应的二进制。
字符编码涉及到编码和解码两个过程。
ASCII码:英文;
国际标准组织制定ISO-8859-1(latin-1):向上兼容ASCII;
GB2312<GBK<GB18030:简体中文;
big5:繁体中文。
在Java中,采用Unicode编码,支持所有文字,具体的实现包括:UTF-8、UTF-16、UTF-32…
char可以存储一个汉字。
转义字符
\u表示后面的事一个字符的unicode编码。unicode编码是十六进制的。
例如:
char x='\u4e2d';
System.out.println(x);
//输出:中
整数型
进制
//十进制
int a=10;
//八进制
int b=010;
//十六进制
int c=0x10;
//二进制
int d=0b10;
默认
在任何情况下,整数型的字面量默认被当作int类型处理,浮点型的字面量默认被当作double类型处理。
当整数型字面量没有超出byte/short/char的取值范围,那么这个整数型字面量可以直接赋值给byte/short/char。
多种数据类型做混合运算的时候,最终的结果是最大容量对应的类型,但是byte、char、short做混合运算的时候,各自先转换成int。
char c1='a';
byte b=1;
short s=c1+b; //理应是98,但是编译报错:从int转换到short可能会有损失,因为编译器不知道结果
short k=98; //编译通过
short s1=(short)c1+b; //编译报错
short s=(short)(c1+b); //编译通过
int a=1;
short x=a; //编译报错,编译器只知道a是int类型,不知道a中存储的是哪个值
System.out.println(x);
自动类型转换
小容量可以自动转换成大容量。
容量排序:
byte<short/char<int<long<float<double
例如:
//int自动转换成long
long b=200;
long e=2147483648;
//编译报错,超过int取值范围
强制类型转换
大容量不能直接赋值给小容量,需要使用强制类型转换符进行强制转换,但是运行时可能损失精度。
long x=100L;
int y=x;
//编译报错
二进制原码反码补码
反码是原码的符号位不变,其他位取反;补码是反码+1。
例如:
byte b=(byte)150;
//10010110(补码)
//10010101(反码)
//11101010(原码)
System.out.println(b);
//输出:-106
字符串连接运算符
当+运算符两边的任意一边是字符串类型,那么这个+会进行字符串拼接操作。
String属于引用数据类型。
标识符
概念
凡是有权利自己命名的单词都是标识符。例如类名、方法名(main也是,但是是固定的)、变量名、接口名、常量名。
命名规则
标识符只能由数字、字母(包括中文)、下划线、美元符号组成,中间不能有空格。
标识符不能以数字开头。
关键字不能作标识符。
区分大小写。
虽然java中的标识符严格区分大小写,但是对于类名来说,如果一个java源文件中同时出现了A类和a类,那么谁在前就生成谁。
标识符没有长度限制。
在123.java中不能定义public的类。
因为public修饰的类名必须和源文件名保持一致。
命名规范
驼峰命名。
类名、接口名每个单词首字母大写。
变量名、方法名首字母小写,后面每个单词首字母大写。
常量名全部大小,并且单词和单词之间采用下划线衔接。
关键字
java中的所有关键字全部小写,具有特殊含义。
数组操作
遍历数组
使用标准的for
循环可以完成一个数组的遍历。
使用for each
循环,直接迭代数组的每个元素。
public class Main {
public static void main(String[] args) {
int[] ns = { 1, 4, 9, 16, 25 };
for (int n : ns) {
System.out.println(n);
}
}
}
注意:在for (int n : ns)
循环中,变量n
直接拿到ns
数组的元素,而不是索引。
打印元素
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] ns = { 1, 1, 2, 3, 5, 8 };
System.out.println(Arrays.toString(ns));
//输出[1, 1, 2, 3, 5, 8]
}
}
数组排序
Java的标准库已经内置了排序功能,我们只需要调用JDK提供的Arrays.sort()
就可以排序:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
Arrays.sort(ns);
System.out.println(Arrays.toString(ns));
//输出[8, 12, 18, 28, 36, 50, 65, 73, 89, 96]
}
}
如果对一个字符串数组进行排序,例如:
String[] ns = { "banana", "apple", "pear" };
排序前,这个数组在内存中表示如下:
┌──────────────────────────────────┐
┌───┼──────────────────────┐ │
│ │ ▼ ▼
┌───┬─┴─┬─┴─┬───┬────────┬───┬───────┬───┬──────┬───┐
ns ─────>│░░░│░░░│░░░│ │"banana"│ │"apple"│ │"pear"│ │
└─┬─┴───┴───┴───┴────────┴───┴───────┴───┴──────┴───┘
│ ▲
└─────────────────┘
调用Arrays.sort(ns);
排序后,这个数组在内存中表示如下:
┌──────────────────────────────────┐
┌───┼──────────┐ │
│ │ ▼ ▼
┌───┬─┴─┬─┴─┬───┬────────┬───┬───────┬───┬──────┬───┐
ns ─────>│░░░│░░░│░░░│ │"banana"│ │"apple"│ │"pear"│ │
└─┬─┴───┴───┴───┴────────┴───┴───────┴───┴──────┴───┘
│ ▲
└──────────────────────────────┘
原来的3个字符串在内存中均没有任何变化,但是ns
数组的每个元素指向变化了。
二维数组
public class Main {
public static void main(String[] args) {
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }
};
System.out.println(ns.length); // 3
}
}
因为ns
包含3个数组,因此,ns.length
为3
。
二维数组的每个数组元素的长度并不要求相同,例如,可以这么定义ns
数组:
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6 },
{ 7, 8, 9 }
};
要打印一个二维数组,可以使用两层嵌套的for循环:
for (int[] arr : ns) {
for (int n : arr) {
System.out.print(n);
System.out.print(', ');
}
System.out.println();
}
或者使用Java标准库的Arrays.deepToString()
:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }
};
System.out.println(Arrays.deepToString(ns));
//输出[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!