前言:
最近打比赛发现很多题都是java的,没学打不出来太吃亏了,所以蹭着有空学习一下。因为主要是要学习java安全所以该文章对语法之类的介绍并不会很详细只是简单了解。
一、java基础
因为之前就已经配过jdk那些的了,所以这里就不多加阐述该怎么配了直接进入正题
概述
Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称。
特点:
- 面向对象(封装,继承,多态);
- 平台无关性,平台无关性的具体表现在于,Java 是“一次编写,到处运行(Write Once,Run any Where)”的语言,因此采用 Java 语言编写的程序具有很好的可移植性,而保证这一点的正是 Java 的虚拟机机制。在引入虚拟机之后,Java 语言在不同的平台上运行不需要重新编译。
- 可靠性、安全性;
- 支持多线程。C++ 语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而 Java 语言却提供了多线程支持;
- 支持网络编程并且很方便。Java 语言诞生本身就是为简化网络编程设计的,因此 Java 语言不仅支持网络编程而且很方便;
- 编译与解释并存;
三个体系:
- JavaSE(J2SE):Java标准版。主要是Java技术的核心和基础。主要运行在桌面级应用程序,如Windows应用程序。
- JavaEE(J2EE):Java企业版。这是Java针对企业级应用开发所提供的一套解决方案,主要用于架构设置高性能企业网站。
- JavaME(J2ME):Java小型版。主要是Java移动设备应用所提供的整套解决方案,主要运行在手机、pad等移动端。
JVM、JRE和JDK:
- JVM(Java Virtual Machine,Java 虚拟机):JVM 是 Java 的运行时引擎,负责执行编译后的 Java 字节码(
.class
文件)。 - JRE(Java Runtime Environment,Java 运行时环境):JRE 是运行 Java 程序的最小环境,包含 JVM 和运行 Java 程序所需的基础类库(如
rt.jar
)。 - JDK(Java Development Kit,Java 开发工具包):JDK 是开发 Java 程序的完整工具包,包含 JRE + 开发工具。
三者关系:
1 | JDK = JRE + 开发工具 |
通俗点说,可以把JDK类比为一个完整的厨房(食材+刀具+厨师),把JRE类比为餐厅(食材+厨师),把JVM类比为 厨师(实际执行烹饪的人)。
基础语法
注释
学每个语言必学部分——注释
跟php的注释差不多,java的注释分为三种
- 单行注释:
//注释
- 多行注释:
/*注释*/
- 文档注释(了解即可):
/**注释*/
关键字
关键字:是java中预先定义的、具有特定语法功能的保留标识符。被设计用于表示程序的结构、逻辑或操作,不能作为变量名、函数名或其他用户自定义标识符。
常见关键字(目前先了解即可):
1 | abstract, assert, boolean, break, byte, case, catch, char, class, |
几个比较重要的关键字:
- class:定义类的基本结构。(同php、C#)
- public:公开访问权限(类、方法、变量均可使用)。
- static:静态成员(属于类而非实例)。
- void:无返回值的方法。(同C#)
- new:创建对象实例。(同php)
- return:从方法中返回值或结束方法。(同php、python)
- import:导入其他包的类。(同python)
基本的程序结构
了解完注释和关键字后我们就可以写出一个基本的java程序结构了
1 | /** |
字面量
字面量: 是直接在代码中表示固定值的符号。它们是源代码中直接写出的数据,无需通过变量或计算来获取。
类型 | 说明 | 举例 |
---|---|---|
整数类型 | 十进制、二进制、十六进制等等 | 10, -5, 0b1010, 0xA, 100L |
小数类型 | 浮点数、单精度、双精度等等 | 3.14, -0.5, 6.022e23, 3.14F, 3.14D |
字符串类型 | 双引号包裹的字符序列 | “Hello, TG1u” |
字符类型 | 单引号包裹的单个字符及转义字符 | ‘A’, ‘9’, ‘$’, ‘\n’ |
布尔类型 | 布尔值,表示真假 | true、false |
空类型 | 一个特殊的值,空值 | null |
变量
变量:是程序的基本组成单元,用于存储和操作数据。
定义格式:
1 | 数据类型 变量名 = 数据 |
使用方式:
输出打印
1
2
3
4
5
6public class TG1u {
public static void main(String[] args) {
int x = 100;
System.out.println(x); // 100
}
}参与计算
1
2
3
4
5
6
7public class TG1u {
public static void main(String[] args) {
int x = 100;
int y = 200;
System.out.println(x + y); // 300
}
}修改记录的值
1
2
3
4
5
6
7
8public class TG1u {
public static void main(String[] args) {
int x = 100;
System.out.println(x); // 100
x = 200;
System.out.println(x); // 200
}
}
数据类型
上面变量的使用格式提到了数据类型,这里就来具体讲一下
数据类型主要分为
基本数据类型: Java 内置的、不可再拆分的数据类型,直接存储数据值,存放在栈内存中。
引用数据类型:存储的是对象的引用(内存地址),实际对象存储在堆内存中。所有引用类型的默认值为
null
。
基本数据类型:
数据类型 | 关键字 | bit | 字节 | 封装类 | 数据范围 | 默认值 |
---|---|---|---|---|---|---|
整数 | byte |
8 | 1 | Byte |
-128~127 | 0 |
short |
16 | 2 | Short |
-32768~32767 | 0 |
|
int |
32 | 4 | Integer |
-2147483648~2147483647 | 0 |
|
long |
64 | 8 | Long |
-922337203685477808~9223372036854775807 | 0L (L大小写都可以) |
|
浮点数 | float |
32 | 4 | Float |
-3.401298e-38~3.402823e+38 | 0.0fF (F大小写都可以) |
double |
64 | 8 | Double |
-4.9000000e-38~1.797693e+308 | 0.0D |
|
布尔 | boolean |
1 | 不确定 | Boolean |
true 或 false |
false |
字符 | char |
16 | 2 | Character |
0-65535 | u0000 |
整数和浮点数的取值范围大小关系:double>float>long>int>short>byte
常见引用数据类型:(暂时了解即可)
数据类型 | 默认值 |
---|---|
数组 | null |
类 | null |
接口 | null |
流程控制
输入和输出
输入
这里就需要导入一个java已经写好自带的类Scanner
,System.in
代表标准输入流。要读取用户输入的字符串,使用scanner.nextLine()
;要读取用户输入的整数,使用scanner.nextInt()
。
1 | import java.util.Scanner; |
输出
输出就比较简单了上面也已经用到好多了,输出主要分为标准输出和格式化输出。
标准输出:print、println
System.out.print
:输出不换行。System.out.println
:print line
的缩写,输出自动换行
1 | public class Main { |
格式化输出:printf
System.out.printf()
:通过使用占位符%?
,printf()
可以把后面的参数格式化成指定格式,并且printf()
也是无法自动换行的。占位符 说明 %d 格式化输出整数 %x 格式化输出十六进制整数 %f 格式化输出浮点数 %e 格式化输出科学计数法表示的浮点数 %s 格式化字符串
1 | public class Main { |
条件判断
if else
跟Python以及php等语言都一样,都是用if
、else if
、else
来进行条件判断
1 | import java.util.Scanner; |
这里的时候还涉及到一个判断引用类型比较的问题
为什么不是name == "TG1u"
而是"TG1u".equals(name)
,这是因为==
比较的是对象的内存地址,而非内容。即使字符串内容相同,用 new String("TG1u")
或不同方式生成的字符串对象,==
可能返回 false
,所以我们这里用equals()
来比较内容
switch
跟C语言的用法差不多,这种条件判断主要是用于多重选择,根据某个表达式的结果,分别去执行不同的分支。
1 | import java.util.Scanner; |
根据输入的name会给出三种情况
但是如果输入的name不在这个三个里,就会返回default
循环
循环跟C、Python等一样也是分为for
、while
、do while
for
Java使用最广泛的就是是for
循环(当然我其他语言用的最多的也是for),for
循环会先初始化计数器,然后,在每次循环前检测循环条件,在每次循环后更新计数器。
1 | //输出1到100相加 |
1 | //输出数组中的奇数 |
数组(
int[]
)用length
获取长度,集合(List
)用size()
获取长度,字符串(String
)用length()
获取长度。
for
循环还可以缺少初始化语句、循环条件和每次循环更新语句
1 | // 不设置结束条件: |
for each
for each
循环可以更简单地遍历数组,for each
循环的变量n不再是计数器,而是直接对应到数组的每个元素。
1 | //输出数组中的偶数 |
while
while
循环在每次循环开始前,首先判断条件是否成立。如果计算结果为true
,就把循环体内的语句执行一遍,如果计算结果为false
,那就直接跳到while
循环的末尾,继续往下执行。
1 | //输出1到100相加 |
注意:写while语句需要注意条件不能是永远满足,否则会造成死循环导致CPU直接占用
100%
了解:Java的
int
类型有最大值,达到最大值后,再加1会变成负数,导致意外退出了while
循环
do while
do while
循环则是先执行循环,再判断条件,条件满足时继续循环,条件不满足时退出。
1 | public class Main { |
注意:跟while一样不要造成死循环
二、面向对象编程
之前学php反序列化的时候其实就已经了解过面向对象的思想了,这里也是简单回顾一下