课程来源
狂神(kuangstudy):KuangStudy
基本概念
集成开发环境(IDE)
集成开发环境(IDE)是为程序员提供代码编写、调试、编译和运行等一体化功能的软件工具。
现在主流的IDE是:IDEA
JAVA三大版本
- JavaSE:标准版(桌面程序,控制台开发)
- JavaME:嵌入式开发(移动端、家电控制端)
- JavaEE:企业级开发(WEB端、服务器开发)
JDK 、JRE、JVM
- JDK(Java Development Kit):JAVA开发者工具,包含了JRE,一般安装这个即可
- JRE(Java Runtime Environment):JAVA运行环境
- JVM(Java Virtual Machine):JAVA虚拟机,JAVA程序运行在JAVA虚拟机中,包含在JRE和JDK中
JAVA文件类型
- .java:java源代码文件,可以直接用文本类浏览工具打开(未经编译的)
- .class:java字节码文件,给JVM虚拟机执行用,不可直接用文本类浏览工具打开(将源代码进行编译后的产物)
Java运行机制
- 编译型
- 代码在执行前需要通过编译器转换成机器码。
- 编译后的程序可以直接在硬件上运行,通常不需要额外的解释器。
- 编译过程可能包括多个阶段,如预处理、编译、汇编和链接。
- 优点包括运行速度快和资源占用低。
- 缺点是编译后的程序通常与特定平台绑定,跨平台性较差。
- 解释型
- 代码在执行时由解释器逐行解释执行,不需要编译成机器码。
- 通常更易于跨平台运行,因为解释器可以在不同的操作系统上实现。
- 优点是开发速度快,易于调试和跨平台。
- 缺点是运行速度通常比编译型语言慢,因为每次执行都需要解释。
数据类型
JAVA是强类型语言,要求变量的使用要符合规定,所有变量都需要先定义后才能使用
- 基本类型
- 整数类型
- byte占一个字节(-128 – 127)
- short占两个字节(-32768 – 32767)
- int占四个字节(-2147483648 – 2147483647)
- long占八个字节(long num = 123456789L)
- 浮点类型
- float占四个字节
- double占八个字节
- 字符类型
- char占八个字节
- 布尔(boolean)类型
- 占一位(1/8字节),且只有true和false两个
- 整数类型
- 引用类型
- 类
- 接口
- 数组
类型转换
- JAVA是强类型语言,运算中,不同类型的数据需要先转换为同一类型,然后进行运算。
- 不能对布尔进行转换
- 不能把对象类型转换为不相关的类型
- 高容量转为低容量可能存在内存溢出或者精度问题
//类型强制转换
double i = 128;
int num = (int)i;
变量
概念:变量就是可以变化的量
JAVA变量是程序中最基本的存储单元,要素包含变量名,变量类型和作用域。变量声明必须以;结束。
//概念
type varName = [value];
//举例
int num = 1;
变量作用域
- 类变量
- 实例变量
- 局部变量
public class Variable {
static int num = 0; //类变量
String name = "GetShell"; //实例变量
public void method() {
int i = 0; //局部变量
}
}
常量
常量(Constant):初始化后不能再改变的值!不会变动的值。常量的值被设定后,程序运行过程中不允许被改变。常量名一般为大写。
public class Main {
//final代表常量
static final String name = "Getshell";
public static void main(String[] args) {
}
}
变量的命名规范
- 所有变量、方法、类名:见名知意
- 类成员变量:首字母小写,后面用驼峰原则,例如:lastName
- 局部变量:首字母小写和驼峰原则
- 常量:大写字母和下划线,例如:MAX_VALUE
- 类名:首字母大写和驼峰原则:Name
- 方法名:首字母小写和驼峰原则,例如:runTo
运算符
- 算数运算符: + – * / % ++ —
- 赋值运算符:=
- 关系运算符:> < >= <= == != instanceof
- 逻辑运算符:&& || !
- 位运算符:& |
- 条件运算符:? :
- 扩展复制:+= -= *= /=
包机制
软件包的本质就是文件夹,一般利用域名倒过来作为域名,例如:com.getshell
如果新建的java类,在其他的软件包里面,需要根据路径在最开头导入包,例如:package com.getshell.demo;
如果要用其他包的类方法,就需要导包,例如:java.util.Date;
JavaDoc
javadoc就是用来生成自己的API文档,需要先加一些固定注释,然后生成!
/**
* @author sibei
* @version 1.0
* @since 1.1
*
*/
Java基本语法
基本运行代码
源代码:Main.java
public class Main {
public static void main(String[] args){
System.out.println("hi,Getshell");
}
}
编译后:Main.class
javac Main.java
运行编译后的文件
PS D:\Project\Java\One\demo.1\src\main\java> java Main
hi,Getshell
注释
概念:Java中的注释是用来解释代码的文字,它们会被编译器忽略,不会影响程序的执行。
- 单行注释
// 单行注释
- 多行注释
/*
多行注释1
多行注释2
*/
- 文档注释
标识符
概念
- JAVA所有组成部分都需要名字,类名、变量名以及方法名都成为标识符。在JAVA内部的起名不能使用标识符的名字。
- 所有的标识符的开头都应该以字母 或 $ 或 _ ,例如:String name | String _name | String $name
Java流程控制
Scannner对象
可以通过Scanner类获取用户的输入
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.print("输入:");
//接收输入
String str = scanner.nextLine();
System.out.println(str);
scanner.close();
}
}
顺序结构
- 顺序结构是最简单的算法结构
- JAVA的基本结构就是顺序结构,除非特别指明,否则就是按照顺序执行
if单选择结构
语法
if(布尔表达式){
//如果布尔表达式为true
}
else{
//如果布尔表达式为false
}
示例代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner_str = new Scanner(System.in);
System.out.print("输入:");
//接收输入
String str = scanner_str.nextLine();
//判断是否为相同
if (str.equals("GetShell")){
System.out.println("GetShell yes");
}
else {
System.out.println("END!");
}
scanner_str.close();
}
}
if多选择结构
语法
if(布尔表达式){
//如果布尔表达式为true
}
else if(布尔表达式){
//如果布尔表达式为true
}else{
//如果布尔表达式为false
}
示例代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//创建一个扫描器对象,用于接收键盘数据
Scanner score_input = new Scanner(System.in);
System.out.print("输入成绩:");
//接收输入
int score = score_input.nextInt();
//判断是否为相同
if (score == 100) {
System.out.println("满分!");
} else if (score >=90){
System.out.println("优秀!");
}else if (score >=60){
System.out.println("及格!");
}
else {
System.out.println("不及格!");
}
score_input.close();
}
}
switch多选择结构
示例代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
char grade = 'C';
switch (grade) {
case 'A':
System.out.println("优秀");
break;
case 'B':
case 'C':
System.out.println("良好");
break;
case 'D':
System.out.println("及格");
break;
case 'F':
System.out.println("你需要再努力努力");
break;
default:
System.out.println("未知等级");
}
System.out.println("你的等级是 " + grade);
}
}
while循环
代码示例
public class Main {
public static void main(String[] args) {
int i = 0;
int sum = 0;
while (i <= 100) {
sum += i++;
}
System.out.println(sum);
}
}
do while循环
代码示例
public class Main {
public static void main(String[] args) {
int i = 0;
int sum = 0;
do {
sum += i++;
} while (i <= 100);
System.out.println(sum);
}
}
for循环
语法格式
for(初始化;布尔表达式;更新){
//代码语句
}
代码示例
public class Main {
public static void main(String[] args) {
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
System.out.println(sum);
}
}
for循环数组
示例代码
public class Main {
public static void main(String[] args) {
int[] number = {1, 2, 3, 4, 5};
for (int num : number) {
System.out.println(num);
}
}
}
JAVA方法
概念
JAVA方法是语句的集合,他们在一起执行一个功能。方法是解决一类问题的步骤的有序组合,方法包含于类或对象中,方法在程序中被创建,在其他地方被引用。JAVA的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段。
public class Main {
public static void main(String[] args) {
System.out.println(add(5,10));
}
// 加法方法
public static int add(int a, int b) {
return a + b;
}
}
方法调用
调用方法:对象名.方法名(实参列表)
举例:int num = add(10,20);
方法的重载
重载就是在一个类中,有相同的函数名称,但是形参不一样的函数。
public class Main {
public static void main(String[] args) {
System.out.println(add(5,10));
System.out.println(add(10.5,11.2));
}
public static int add(int a, int b) {
return a + b;
}
public static double add(double a, double b) {
return a + b;
}
}
命令行传参
编译:javac Main.java
执行:java Main 111 222
public class Main {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
可变参数
Java支持传递同类型的可变参数给一个方法,在方法声明中,在指定参数类型后加一个省略号(…)。一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
public class Main {
public static void main(String[] args) {
System.out.println(sum(1, 2, 3));
}
public static int sum(int... num) {
int sum = 0;
for (int i = 0; i < num.length; i++) {
sum += num[i];
}
return sum;
}
}
递归
递归简单来说就是:自己调用自己的方法。递归结构包含两个部分:
- 递归头:什么时候不调用自身方法
- 递归体:什么时候需要调用自身方法
public class Main {
public static void main(String[] args) {
System.out.println(jc(5));
}
public static int jc(int x) {
if (x == 1) {
return 1;
} else {
return x * jc(x - 1);
}
}
}
数组
首先必须要声明数组才能使用数组,数组的索引从0开始。数组的长度是确定的,一旦被创建大小就不可以改变。数组的元素必须是相同的类型,不允许出现混合类型。
数组声明方法:变量的类型 变量的名字=变量的值;
// 静态初始化
int[] age = {18, 15, 21};
// 动态初始化
int[] nums;
nums = new int[10];
nums[0]=1;
遍历数组
public class Main {
public static void main(String[] args) {
int[] age={10,30,18,46,60};
//打印全部数据元素
for (int i = 0; i < age.length; i++) {
System.out.println(age[i]);
}
//打印全部数据元素
for(int x:age){
System.out.println(x);
}
}
}
多维数组
多维数组可以看为数组的数组,例如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
// 二维数组
int num[][]= new int[2][6];
Arrays类
概念:就是针对数组,在JAVA中自带方法Arrays
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] nums = {10, 2020, 874, 548, 45, -45};
//打印数组内所有的元素
System.out.println(Arrays.toString(nums));
//数组升序排序
Arrays.sort(nums);
System.out.println(Arrays.toString(nums));
}
}
方法组成
public class Demo {
public static void main(String[] args) {
}
/*
修饰符 返回值类型 方法名(...){
//方法名
return 返回值;
}
*/
public String Say() {
return "Hello World";
}
}
静态方法和非静态方法调用
如果调用静态方法,直接类名.方法名即可,而如果要调用非静态方法,则需要先声明再调用。
Main.java
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 非静态方法调用
// 对象类型 对象名 = 对象值
People people = new People();
people.say();
//静态方法调用
People.love();
}
}
People.java
public class People{
public void say(){
System.out.println("hi , sibei");
}
public static void love(){
System.out.println("hi , sinan");
}
}
面相对象编程(OOP)
本质:以类的方式组织代码,以对象的形式封装数据。先有类,再有对象。类是对象的模板
三大特性:封装、继承、多态
对象:指具体的事物
抽象:把对象的一些特征“抽取出来”,比如做一个学生管理系统,只需要学生的学号、姓名即可。
创建与初始化对象
Main.java
//一个项目应该只有一个main方法
public class Main {
public static void main(String[] args) {
// 类的实例化
// 类实例化后会返回一个自己的对象
// student对象就是一个student类的具体示例
Student sibei = new Student();
sibei.name = "sibei";
sibei.age = 20;
sibei.study();
}
}
Student.java
//学生类
public class Student {
//属性:字段
String name;
int age;
//方法
public void study() {
System.out.println(this.name + "在学习,年龄"+this.age);
}
}
构造方法
构造方法是Java中的特殊方法,用于初始化对象。它与类同名,没有返回类型。构造方法可以有参数,以便在创建对象时传递初始值;如果没有定义,Java会提供一个默认构造方法。可以重载构造方法,以支持不同的初始化方式。
Main.java
public class Main {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);
}
}
Person.java
public class Person {
String name;
//构造方法
//用于在使用初始化实例的时候初始化属性
//也就是在实例化类的时候就会执行构造方法
public Person() {
this.name = "sibei";
}
}
封装
Java的封装(Encapsulation)是一种面向对象编程(OOP)的核心概念,它指的是将对象的状态(属性)和行为(方法)捆绑在一起,并对对象的内部实现进行隐藏。封装提供了一种限制对某些组件访问的方式,以保护对象内部数据不被外部直接访问和修改。
IDEA快速插入Setter和Getter快捷键:Alt+insert
Main.java
public class Main {
public static void main(String[] args) {
Person sibei = new Person();
sibei.setName("sibei");
sibei.setId(1);
System.out.println("ID: " + sibei.getId() + " ,Name: " + sibei.getName());
}
}
Person.java
public class Person {
//private 属性私有 不能直接调用
private String name;
private int id;
//对封装的属性,可以用public属性的get和set方法来操作这些属性
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
继承
- 继承的本质是对某一批类的抽象。
- extends的意识是扩展,子类是父类的扩展。
- Java中所有的类都默认继承Object类
- 继承是类和类之间的一种关系。除此以外,类和类之间的关系还有依赖、组合、聚合等。
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
- 正常情况下,子类继承父类后,拥有父类全部方法
Main.java
public class Main {
public static void main(String[] args) {
Student sibei = new Student();
sibei.Say();
}
}
Person.java
public class Person {
public void Say(){
System.out.println("Hi , sibei");
}
}
Student.java
public class Student extends Person{
}
Super关键词
Super主要是用来找父类的变量和方法之类的
Main.java
public class Main {
public static void main(String[] args) {
Student stu = new Student();
stu.Say("糸北");
System.out.println("--------");
stu.SayHello_test();
}
}
Person.java
import org.w3c.dom.ls.LSOutput;
public class Person {
// Super可以访问到父类的变量
protected String name = "sibei";
// 父类的方法
public void SayHello(){
System.out.println("Hi, sibei");
}
}
Student.java
public class Student extends Person{
private String name="sinan";
public void Say(String name){
// 输出的是传递的变量
System.out.println(name);
// 输出这个类里面的name变量
System.out.println(this.name);
// Super可以输出父类的变量
System.out.println(super.name);
}
public void SayHello(){
System.out.println("Hi, sinan");
}
public void SayHello_test(){
//执行当前类的方法
SayHello();
//执行当前类的方法
this.SayHello();
//执行父类的方法
super.SayHello();
}
}
方法重写
在Java中,方法重写(Method Overriding)是一种面向对象编程(OOP)的特性,它允许子类有一个与父类同名的方法。这样做的目的通常是为了改变子类对象调用该方法时的行为。
想象一下,你有一个父类叫做“动物”,它有一个方法叫做“叫声”,这个方法在父类中可能是一个通用的行为,比如发出“咕咕”的声音。然后你有一个子类叫做“狗”,狗的叫声显然和一般的动物不一样,它们会“汪汪”叫。
在Java中,你可以这样实现:
class Animal {
public void makeSound() {
System.out.println("Goo goo");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof woof");
}
}
在这个例子中,狗
类重写了动物
类的叫声
方法。当你创建一个狗
对象并调用叫声
方法时,它会执行狗
类中定义的叫声
方法,输出“汪汪”,而不是父类中的“咕咕”。
方法重写需要满足以下条件:
- 方法名和参数列表必须与被重写的方法完全相同。
- 返回类型应该与被重写的方法兼容。
- 访问权限不能比被重写的方法更严格。
- 重写的方法不能抛出新的检查异常或者比被重写的方法声明更广泛的检查异常。
使用@Override
注解是可选的,但它可以帮助编译器检查你是否真的重写了父类的方法,如果父类中没有这个方法,编译器会报错。
这就是方法重写的基本概念,它使得子类能够根据需要定制或改变继承自父类的行为。
多态
想象一下,你有一个玩具箱,里面有不同类型的玩具车,比如小汽车、卡车和摩托车。你有一个遥控器,这个遥控器可以控制所有这些玩具车,让它们前进。尽管你按的是同一个按钮,但不同类型的玩具车前进的方式可能不同。
在Java中,多态就像是这个遥控器。你有一个父类(比如叫做ToyCar
),它有一个方法(比如叫做move
)。然后你有多个子类(比如Car
、Truck
和Motorcycle
),它们都继承自ToyCar
类,并且重写了move
方法,以实现各自的移动方式。
这里是代码示例:
// 父类:玩具车
class ToyCar {
public void move() {
System.out.println("玩具车在移动");
}
}
// 子类:小汽车
class Car extends ToyCar {
@Override
public void move() {
System.out.println("小汽车快速前进");
}
}
// 子类:卡车
class Truck extends ToyCar {
@Override
public void move() {
System.out.println("卡车缓慢前进");
}
}
// 子类:摩托车
class Motorcycle extends ToyCar {
@Override
public void move() {
System.out.println("摩托车灵活前进");
}
}
public class Main {
public static void main(String[] args) {
ToyCar myCar1 = new Car();
myCar1.move(); // 输出:小汽车快速前进
ToyCar myCar2 = new Truck();
myCar2.move(); // 输出:卡车缓慢前进
ToyCar myCar3 = new Motorcycle();
myCar3.move(); // 输出:摩托车灵活前进
}
}
在这个例子中:
ToyCar
是一个父类,有一个move
方法。Car
、Truck
和Motorcycle
是子类,它们都重写了move
方法。- 在
Main
的main
方法中,我们创建了Car
、Truck
和Motorcycle
的对象,并将它们赋值给ToyCar
类型的引用。 - 当我们调用
move
方法时,Java会在运行时确定对象的实际类型,并调用相应的move
方法。
这就是多态:同一个操作(比如move
),在不同的对象上可以有不同的行为。多态让程序更加灵活和可扩展。
抽象类
- 抽象类不能被实例化,只能靠子类来实现(子类继承抽象类后重写抽象类的方法)
Main.java
public class Main {
public static void main(String[] args) {
// 调用继承抽象类并且重写后方法
new Setting().Say();
}
}
Action.java
// 关键词用abstract 变为抽象类
public abstract class Action {
// 抽象方法 只有名字 没有实际功能
public abstract void Say();
}
Setting.java
// 使用抽象类的方法,需要集成,然后重写
public class Setting extends Action{
@Override
public void Say() {
System.out.println("抽象,太抽象了");
}
}
接口
在Java中,接口(Interface)是一种完全抽象的结构,它允许你定义方法,但不能实现它们。接口可以被看作是一种规范,它规定了类应该遵循的规则和方法,但不提供实现细节。其他类可以实现这些接口,从而提供具体的方法实现。implements可以实现多个接口。如果实现接口,就必须要重写接口中的方法。接口不能直接调用,只能调用实现接口的方法。
Main.java
public class Main {
public static void main(String[] args) {
new UserServiceDel().add(1);
new UserServiceDel().delete(2);
}
}
UserService.java
// interface定义关键词,接口都需要有实现类
public interface UserService {
void add(int id);
void delete(int id);
}
UserServiceDel.java
// implements 实现接口方法用到的关键词
// 实现接口的类,就必须要重写接口的类
public class UserServiceDel implements UserService{
@Override
public void delete(int id) {
System.out.println("通过接口,执行delete方法");
}
@Override
public void add(int id) {
System.out.println("通过接口,执行add方法");
}
}
异常
Java的异常机制是用于处理程序运行过程中可能出现的错误或异常情况的一种机制。它允许程序在出现异常时采取适当的措施,从而避免程序崩溃。
以下是Java异常机制的几个关键概念:
- 异常类:Java中所有异常都是从
Throwable
类派生的。常见的子类包括Exception
和Error
。Exception
用于处理程序可恢复的异常,而Error
表示严重问题,通常不应由应用程序处理。 - 检查异常(Checked Exception):这些异常在编译时必须被处理(例如,
IOException
)。如果方法可能抛出检查异常,必须要么捕获它,要么在方法签名中声明。 - 非检查异常(Unchecked Exception):这些异常在运行时发生,通常是由编程错误引起的(例如,
NullPointerException
)。它们不需要在编译时处理。 - 抛出异常:使用
throw
语句可以手动抛出异常,例如:
throw new IllegalArgumentException("Invalid argument");
- 捕获异常:使用
try-catch
语句块来捕获和处理异常。例如:
try {
// 可能抛出异常的代码
} catch (IOException e) {
// 处理异常的代码
}
- 最终块(finally):
finally
块用于执行一些清理操作,无论是否发生异常,finally
中的代码都会执行。例如:
try {
// 可能抛出异常的代码
} catch (Exception e) {
// 处理异常的代码
} finally {
// 清理操作
}
- 自定义异常:可以通过扩展
Exception
类或RuntimeException
类来创建自定义异常。
Main.java
public class Main {
public static void main(String[] args) {
int a = 100;
int b = 0;
try {
System.out.println(a/b);
}catch (ArithmeticException e){
System.out.println("异常!");
}
}
}
注解与反射
注解
Java注解(Annotations)是一种特殊的接口,用于为代码提供元数据。注解不会直接影响代码的执行,但可以通过反射机制读取注解信息,从而影响程序的行为。注解可以用来标记类、方法、变量、参数等,以提供额外的信息,例如编译时检查、运行时处理、代码分析等。
Java注解有多种用途,以下是一些常见的注解类型:
@Override:表示某个方法声明打算重写基类中的一个方法。
@Override
public String toString() {
return "Some value";
}
@Deprecated:表示某个元素(类、方法、字段等)已经过时,不建议使用。
@Deprecated
public void oldMethod() {
// ...
}
@SuppressWarnings:告诉编译器忽略特定的警告。
@SuppressWarnings("unchecked")
public void test() {
// ...
}
@Retention 和 @Target:这两个注解用于定义注解的属性。
- @Retention 指定了注解的保留策略,即注解信息在什么级别可用(源代码、类文件、运行时)。
- @Target 指定了注解可以应用的Java元素类型(例如类、方法、字段等)。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String value();
}
自定义注解:可以创建自定义注解来标记代码,并通过反射读取这些注解信息。
public @interface Todo {
String value();
}
@Todo("Implement this method")
public void doSomething() {
// ...
}
在上述自定义注解的例子中,Todo
注解可以用来标记需要后续处理的方法。注解的值("Implement this method"
)可以在运行时通过反射读取,并据此执行相应的逻辑,比如生成待办事项列表。
使用注解时,需要在代码中导入 java.lang.annotation
包,因为注解类型都在这个包下。此外,自定义注解需要定义在接口中,并且使用 @interface
关键字。自定义注解可以有属性,这些属性在注解使用时必须指定。
暂无评论内容