简介
Java 特点
- Write once, run anywhere,跨平台能力
- Java 通过GC(Garbage Collector)回收分配内存,大部分情况下不需要自己操心内存的分配和回收
相关概念
- Java 程序执行过程。
.java
(代码)-(编译)->.class
字节码文件–>虚拟机
解释执行 - JDK: Java 开发工具包(Java Development Kit)。包括两个组件:
- 开发工具集,如Javac(编译器,把源程序转为字节码),
- JRE(Java Runtime Environment)。包括JVM(Java Virtual Machine,Java虚拟机,是Java平台无关性的关键),Java核心类库和支持文件。
- Jar(Java Archive):Java归档文件格式,用于将Java类文件、资源文件和其他相关文件打包到一个单独的文件中。Jar文件通常用于分发和部署Java应用程序和库。
- Maven(Apache Maven):用于构建和管理Java项目的自动化构建工具。它使用POM(Project Object Model)文件来描述项目的依赖关系、构建配置和项目结构。
Java平台
- Java SE:Java 标准版,用来开发桌面程序。
- Java EE:Java 企业版,多了Web程序开发。
- Java ME:Java 微型版,用来移动设备开发。用的越来也少了。
Java 安装
手动安装:
- JDK 去 oracle 官网下载。https://www.oracle.com/downloads/
- 查看版本
Java -version
- 查看版本
- IDE 去 jetbrain 官网下载 IntelliJ IDEA https://www.jetbrains.com/
- 打开IDE,右键 new -> Module => Maven, 然后开始编程
命令行安装
sudo apt install -y default-jdk
java -version
maven
# 显示引用树
mvn dependency:tree
HelloWorld
// HelloWorld.java
/**
* @author guofei9987
* @version 0.0.1
* 文档型注释,用 java doc 命令自动生成文档
*/
/*
多行注释
*/
// 单行注释
public class HelloWorld {
public static void main(String[] args) {
System.out.println(args[0]);
}
}
javac HelloWorld.java # 用来生成 *.class 字节码
java HelloWorld Hello World # 执行代码,会输出 Hello,这是因为 Wrold 对应 args[1]
代码规范
- 大小写敏感
- 类名:每个单词的首字母大写,例如 MyFirstJavaClass 。
- 方法名:小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
- 变量名:规范同方法名
- 源文件名:源文件名必须和类名相同后缀为.java。
- 主方法入口:所有的Java 程序由public static void main(String[] args)方法开始执行。
- 注释方法类似 C
基本
public class Puppy{
int puppyAge;
public Puppy(String name){
// 这个构造器仅有一个参数:name
System.out.println("Passed Name is :" + name );
}
public void setAge( int age ){
puppyAge = age;
}
public int getAge( ){
System.out.println("Puppy's age is :" + puppyAge );
return puppyAge;
}
public static void main(String []args){
/* 创建对象 */
Puppy myPuppy = new Puppy( "tommy" );
/* 通过方法来设定age */
myPuppy.setAge( 2 );
/* 调用另一个方法获取age */
myPuppy.getAge( );
/*你也可以像下面这样访问成员变量 */
System.out.println("Variable Value :" + myPuppy.puppyAge );
}
}
程序入口是main
数据类型
基本数据类型
6种数字类型,1种字符类型,1种布尔类型
数据类型 | 说明 | 字节 | 最小值 | 最大值 | 默认值 | 例子 |
---|---|---|---|---|---|---|
byte | 8位,有符号,以二进制补码表示,整数 | 1 | -128(-2^7) | 127(2^7-1) | 0 | byte a = 100,byte b = -50 |
short | 16位、有符号的以二进制补码表示的整数 | 2 | -32768(-2^15) | 32767(2^15 - 1) | 0 | short s = 1000,short r = -20000 |
int | 32位、有符号的以二进制补码表示的整数 | 4 | -2,147,483,648(-2^31) | 2,147,483,647(2^31 - 1) | 0 | int a = 100000, int b = -200000 |
long | 64位、有符号的以二进制补码表示的整数 | 8 | 约 -9E18(-2^63) | 约 9E18(2^63 -1) | 0L | long a = 100000L,long b = -200000L |
float | 单精度、32位、符合IEEE 754标准的浮点数,不能用来表示精确的值,如货币 | 4 | 0.0f | float f1 = 234.5F; | ||
double | 双精度、64位、符合IEEE 754标准的浮点数,不能表示精确的值,如货币 | 8 | 0.0d | double d1 = 123.4; double d1 = 123D; double d=.2E5; | ||
boolean | 只有两个取值:true和false | 1 | false | boolean one = true | ||
char | 单一的16位Unicode字符 | 2 | ‘\u0000’(即为0) | ‘\uffff’(即为65,535) | char letter = ‘A’; char ch = 65; char ch1=’\u005d’; |
在赋值或初始化时,可以把“小的”类型赋值给“大的”类型,反过来不行。
进制
- 八进制:0开头,如037,056
- 十六进制:0x或0X开头,如 0x12ab
- 进制也可以指定类型,如 0x123L
字符串
String s="";
- 可以出现 unicode
String s="\u005d\u005fABC";
- 可以用加号连接
str.toUpperCase()
基本数据类型转换
分为自动类型转换,显式的类型转换。
- 自动类型转换:范围小的转为范围大的。
- 显式的类型转换
double d = 12.3; float f = (float) d;
int x = 10, y = 5;
System.out.println("" + x + y); // 105,按照字符串连接
System.out.println(x + y + ""); // 先运算然后字符串连接
System.out.println(' ' + x + y); // char格式被转换为int
常量
指不能改变的量,一般用大写表示。
final double PI = 3.1415927;
String
默认是 null
创建
String s1 = "字符";
String s2 = new String();
String s3 = new String("字符");
str = String.format("整数:%d,浮点数 %f,浮点表示 %g,指数表示 %e %n", 10,10.0, 10.0, 120.0);
//整数:10,浮点数 10.000000,浮点表示 10.0000,指数表示 1.200000e+02
str = String.format("八进制:%o,十六进制:%x,指数十六进制 %a, 布尔表示: %b", 20, 20, 20.0, true);
//八进制:24,十六进制:14,指数十六进制 0x1.4p4, 布尔表示: true
str = String.format("字符串类型:%s,char 类型:%c,hash: %h", "王南", 'A',"A");
//字符串类型:王南,char 类型:A,hash: 41
String c= String.join(" ",new ArrayList<>());
方法
int length();
char charAt(int index) // 返回指定索引处的 char 值。
int compareTo(Object o) // 把这个字符串和另一个对象比较。
int compareTo(String anotherString) // 按字典顺序比较两个字符串。
int compareToIgnoreCase(String str) // 按字典顺序比较两个字符串,不考虑大小写。
String concat(String str) // 将指定字符串连接到此字符串的结尾。
boolean contentEquals(StringBuffer sb) // 当且仅当字符串与指定的StringButter有相同顺序的字符时候返回真。
boolean endsWith(String suffix) // 测试此字符串是否以指定的后缀结束。
boolean equals(Object anObject) // 将此字符串与指定的对象比较。
boolean equalsIgnoreCase(String anotherString) // 将此 String 与另一个 String 比较,不考虑大小写。
byte[] getBytes() // 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
byte[] getBytes(String charsetName) // 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) // 将字符从此字符串复制到目标字符数组。
int hashCode() // 返回此字符串的哈希码。
int indexOf(int ch)// 返回指定字符在此字符串中第一次出现处的索引。
int indexOf(int ch, int fromIndex) // 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。
int indexOf(String str) // 返回指定子字符串在此字符串中第一次出现处的索引。
int indexOf(String str, int fromIndex) // 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
int lastIndexOf(int ch) // 返回指定字符在此字符串中最后一次出现处的索引。
int lastIndexOf(int ch, int fromIndex) // 返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。
int lastIndexOf(String str) // 返回指定子字符串在此字符串中最右边出现处的索引。
int lastIndexOf(String str, int fromIndex) // 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
String intern() // 返回字符串对象的规范化表示形式。
int length() // 返回此字符串的长度。
boolean matches(String regex) // 告知此字符串是否匹配给定的正则表达式。
boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) // 测试两个字符串区域是否相等。
boolean regionMatches(int toffset, String other, int ooffset, int len) // 测试两个字符串区域是否相等。
String replace(char oldChar, char newChar) // 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
String replaceAll(String regex, String replacement) // 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
String replaceFirst(String regex, String replacement) // 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
String[] split(String regex) // 根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex, int limit) // 根据匹配给定的正则表达式来拆分此字符串。
boolean startsWith(String prefix) // 测试此字符串是否以指定的前缀开始。
boolean startsWith(String prefix, int toffset) // 测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
CharSequence subSequence(int beginIndex, int endIndex) // 返回一个新的字符序列,它是此序列的一个子序列。
String substring(int beginIndex) // 返回一个新的字符串,它是此字符串的一个子字符串。
String substring(int beginIndex, int endIndex) // 返回一个新字符串,它是此字符串的一个子字符串。
char[] toCharArray() // 将此字符串转换为一个新的字符数组。
String toLowerCase() // 使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
String toLowerCase(Locale locale) // 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。
String toString() // 返回此对象本身(它已经是一个字符串!)。
String toUpperCase() // 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
String toUpperCase(Locale locale) // 使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。
String trim() // 去除两边的空格
关于 byte:
String s1="JAVA 编程";
byte[] arr=s1.getBytes(StandardCharsets.UTF_8); // String 转 byte[]
for(byte i:arr)System.out.print(i+";");
// byte 转回 String
String s2=new String(arr);
System.out.println(s2);
更多对象
- StringBuffer 线程安全
- StringBuilder 不是线程安全的,但性能略好。而且不再是不可变对象了。
StringBuilder s2=new StringBuilder("你好");
// 可以 append 各种类型
s2.append(',');
s2.append("hello!");
s2.append(1);
s2.delete(3, 8);
s2.insert(4, "HELLO!");
s2.substring(0, 4)
s2.replace
格式化时间
Date date=new Date();
//b的使用,月份简称
String str=String.format(Locale.US,"英文月份简称:%tb",date);
System.out.println(str);
System.out.printf("本地月份简称:%tb%n",date);
//B的使用,月份全称
str=String.format(Locale.US,"英文月份全称:%tB",date);
System.out.println(str);
System.out.printf("本地月份全称:%tB%n",date);
//a的使用,星期简称
str=String.format(Locale.US,"英文星期的简称:%ta",date);
System.out.println(str);
//A的使用,星期全称
System.out.printf("本地星期的简称:%tA%n",date);
//C的使用,年前两位
System.out.printf("年的前两位数字(不足两位前面补0):%tC%n",date);
//y的使用,年后两位
System.out.printf("年的后两位数字(不足两位前面补0):%ty%n",date);
//j的使用,一年的天数
System.out.printf("一年中的天数(即年的第几天):%tj%n",date);
//m的使用,月份
System.out.printf("两位数字的月份(不足两位前面补0):%tm%n",date);
//d的使用,日(二位,不够补零)
System.out.printf("两位数字的日(不足两位前面补0):%td%n",date);
//e的使用,日(一位不补零)
System.out.printf("月份的日(前面不补0):%te",date);
运算符
- 算术运算符
+ - * / // 如果分子分母都是int,结果为int % // 求余数 int y = x++; y = ++x; // 先自增,然后赋值 y = --x; y = x--;
- 赋值运算符
int x = 1; // 普通的赋值 x += 5; x -= 5; x *= 5; x /= 5; x %= 5;
- 关系运算符
>; <; >=; <=; ==;!=; 'A'>'B' // 结果是 false,比较的是 ASCII float f=5.0f; long l=5; f==l; // true, 只要值相等,就返回 true
- 逻辑运算符
& // 与 && // 与,如果第一个为 false,后面就不算了 | //或 || //或快,如果第一个为 true,后面就不算了 ! // 非
- 条件运算符
// 语法:bool?expr1:expr2 // 例子: int x = 1, y = 2; int max = (x > y) ? x : y;
- 位运算符
流程控制
条件语句
if
// if
if(a>b){
System.out.println('yes');
}
// if-else
if(a>b){
System.out.println('yes');
}
else{
System.out.println('no');
}
// 多重if,只会执行一个分支
if(bool1){
expr1;
}
else if(bool2){
expr2;
}
else if(bool3){
expr3;
}
else{
exprn;
}
// 嵌套if,不多说。
// 如果没有大括号,else会匹配到最近的if
switch
switch(bool){
case value1:
expr1;break;
case value2:
expr2;break;
default: // default 可以省略。
expr3;
}
循环语句
while
while(bool){
expr1;
}
// do-while 循环,至少会循环一次。
do{
exp1;
}while(bool1); // 这里必须以分号结尾
for
for(初始化表达式;循环条件表达式;类似n++) // 每个表达式都可以省略,可以把逻辑放到其它地方:初始化表达式可以放for循环之前,循环条件表达式可以在循环体中用break语句代替,自增表达式也可以放循环体。最省略的形式 for(;;;)
{
expr1;
}
int sum = 0;
for (int i = 1; i <= 5; i++) {
int n = 1;
sum += i;
}
// 1. 这里会报错,for循环内定义的变量,作用范围只能在for循环中。
// 2. 如果 int i 在for循环外定义,就不报错,返回6.
System.out.println(i);
System.out.println(n); // 同样报错,原因同上
// 对数组for循环
String [] names ={"James", "Larry", "Tom", "Lacy"};
for(String name:names){
System.out.println(name);
}
// 功能不多说,只对单层循环有效。
break
continue
参考资料
https://www.w3cschool.cn/java/