java 学习基础知识
一、java学习路线
- 入门:学习Java基础知识,了解面向对象编程思想等基本概念。
- 进阶:深入了解Java的高级特性,如多线程编程、网络编程等;学习Java框架,如Spring、Hibernate、MyBatis等。
- 实践:通过实战项目,深入理解Java应用开发过程中的各种问题,提升实践能力和经验。
- 拓展:掌握Java相关技术的发展方向和趋势,例如大数据、人工智能等领域。
具体来说,可以按照以下学习路线进行深入学习:
- Java基础:语法、数据类型、控制语句、面向对象编程等。
- 集合框架:学习Java中的集合类,如ArrayList、LinkedList、Set、Map等,以及它们的使用场景。
- IO流操作:学习Java中的IO流操作,包括标准输入输出、文件操作等。
- 多线程编程:了解Java中的多线程编程原理、并发机制等,掌握线程池、锁、同步等技术。
- 网络编程:学习Java中的网络编程,包括TCP/IP协议、Socket编程、HTTP协议等。
- Java框架:了解常用的Java框架,如Spring、Hibernate、MyBatis等。
- 数据库:学习常用数据库的使用和操作,如MySQL、Oracle、SQL Server等。
- 实战项目:通过实践项目的方式,加深对Java知识的理解和应用能力。
二、知识点
2.1 入门java
2.1 基础知识:
https://www.runoob.com/java/java-tutorial.html
2.1.1 面向对象
面向对象编程(Object-oriented Programming,简称OOP)是一种程序设计范型,其核心思想是将代码组织成对象,通过对象间的交互实现程序的各项功能。
面向对象编程包括三个基本概念:封装、继承和多态。其中:
封装:指隐藏数据细节,仅对外暴露必要的接口,保证数据安全性和代码的可维护性;
继承:指在已有类的基础上创建新的类,新类继承了旧类的属性和方法,并可添加自己的属性和方法,使得代码易于复用和扩展;
多态:指不同对象对同一消息作出不同响应的能力,通过继承和接口实现,可以提高代码的灵活性和可扩展性。
面向对象编程注重代码的可重用性、可维护性和可扩展性,是现代程序设计中非常重要的一种编程思想。在Java语言中,面向对象编程是基本编程范式之一,也是Java语言的核心特征。
2.2 java语法
2.2.1 变量
- 变量声明
在Java中,变量必须先声明后使用。变量的声明格式为:数据类型 变量名;
例如:
int age;
String name;
double salary;
- 变量赋值
变量赋值就是将一个值存储到一个变量中。赋值符号是等号"=",例如:
age = 18;
name = "张三";
salary = 5000.00;
也可以在声明时直接赋值,例如:
int age = 18;
String name = "张三";
double salary = 5000.00;
2.2.2 数据类型
在Java中有8种基本数据类型,分别是:byte、short、int、long、float、double、boolean和char。
其中,byte、short、int和long用于存储整数,float和double用于存储浮点数,boolean用于存储布尔类型,char用于存储字符类型。
2.2.3 运算符
Java中常见的运算符包括算术运算符、赋值运算符、比较运算符、逻辑运算符等等。
例如,算术运算符:+(加)、-(减)、*(乘)、/(除)、%(取余);
赋值运算符:=、+=、-=、*=、/=、%=;
比较运算符:==、!=、<、<=、>、>=;
逻辑运算符:&&(与)、||(或)、!(非)。
2.2.4 控制语句
Java中常用的控制语句有:if语句、switch语句、while循环、do-while循环和for循环等。
例如,if语句:
if (age > 18) {
System.out.println("已成年");
} else {
System.out.println("未成年");
}
switch语句:
switch (weekday) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
...
default:
System.out.println("错误的日期");
break;
}
while循环:
int i = 0;
while (i < 10) {
System.out.println(i);
i++;
}
do-while循环:
int i = 0;
do {
System.out.println(i);
i++;
} while (i < 10);
for循环:
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
2.2.5 方法
方法是一段具有特定功能的代码块,在Java中用关键字“public”、“private”、“protected”等来修饰。
方法包含一个方法头和方法体,方法头指定了方法的名称、参数列表以及返回类型,例如:
public int add(int x, int y) {
return x + y;
}
这个方法的名称是“add”,它有两个整型参数x和y,返回类型为int。方法体中的代码实现了将x和y相加并返回结果的功能。
2.2.6 数组
数组是一组相同类型数据的集合,可以通过索引访问其中的元素。
在Java中创建数组的格式如下:
数据类型[] 数组名称 = new 数据类型[数组长度];
例如:
int[] scores = new int[5];
这就创建了一个有5个整型元素的数组scores。通过索引访问数组元素,例如:
scores[0] = 90;
scores[1] = 80;
scores[2] = 85;
scores[3] = 95;
scores[4] = 75;
for (int i = 0; i < scores.length; i++) {
System.out.println("第" + (i+1) + "个学生的成绩为:" + scores[i]);
}
上述代码中,通过for循环遍历数组中的元素,并输出每个学生的成绩。
2.2.7 类和对象
在Java中,类是一组具有相同属性和方法的对象的抽象描述。对象是类的一个实例。
使用Java创建类的格式如下:
public class 类名 {
// 属性
数据类型 属性名;
...
// 方法
public void 方法名() {
...
}
...
}
例如:
public class Person {
// 属性
private String name;
private int age;
private double height;
// 方法
public void sayHello() {
System.out.println("大家好,我是" + name + ",今年" + age + "岁,身高" + height + "米。");
}
// getter和setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
这个类定义了一个名为“Person”的人类,包含了姓名、年龄、身高等属性和sayHello()方法。其中,getter和setter方法用于获取和设置属性值。
在Java中创建对象的格式如下:
类名 对象名 = new 类名();
例如:
Person p1 = new Person();
这就创建了一个Person类的对象p1。可以通过调用对象的方法和访问对象的属性来实现对对象的操作。
2.2.8 承和多态
继承是一种面向对象的重要特性,它允许一个类继承另一个类的属性和方法。
在Java中继承的格式如下:
public class 子类 extends 父类 {
...
}
例如:
public class Student extends Person {
// 属性
private String school;
// 方法
public void study() {
System.out.println("我在" + school + "学习。");
}
// getter和setter方法
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
这个子类Student继承了父类Person的属性和方法,并添加了自己的属性school和方法study()。
多态是一种在面向对象编程中经常使用的技术,它允许同一个方法在不同的对象上表现出不同的行为。
例如,父类Person中有一个sayHello()方法,子类Student也有一个sayHello()方法,但是它们的实现方式可能不同。在程序运行时,通过父类变量引用子类对象,就可以实现多态。
Person p1 = new Person();
Student s1 = new Student();
p1.sayHello(); // 调用Person类的sayHello()方法
s1.sayHello(); // 调用Student类的sayHello()方法
2.2.9 异常处理
在Java中,异常指程序运行过程中出现的错误情况。为了保证程序的健壮性和可靠性,需要对异常进行处理。
在Java中处理异常的方式有两种:捕获和抛出。
捕获异常使用try-catch语句,例如:
try {
// 可能会抛出异常的代码
} catch (Exception e) {
// 异常处理代码
}
当try块中的代码出现异常时,异常对象会被catch块捕获并处理。
抛出异常使用throw关键字,例如:
public int divide(int a, int b) throws Exception {
if (b == 0) {
throw new Exception("除数不能为0。");
}
return a / b;
}
在这个例子中,如果除数为0,会抛出一个异常对象。调用这个方法时,需要使用try-catch或再次使用throws关键字来处理异常。
2.2.10 接口
接口是一种特殊的抽象类,它只包含了方法的声明而没有实现。在Java中,可以使用关键字“interface”定义一个接口。
接口中定义的方法必须被实现,并且不能有方法体。要实现一个接口,需要使用implements关键字。
例如:
public interface Shape {
public double area();
}
这个接口定义了一个面积的方法area(),实现该接口的类都必须实现area()方法。
public class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double w, double h) {
this.width = w;
this.height = h;
}
public double area() {
return width * height;
}
}
这个Rectangle类实现了Shape接口,并推导出了area()方法的实现方式。
2.2.11 包(package)
Java中的包是一种名字空间,用于组织相关的类和接口。通过包名来区分不同的包。
在Java中,一个包是由同名的文件夹组成的。例如,一个名为com.example的包,对应的文件夹结构如下:
com
└── example
├── MyClass1.java
└── MyClass2.java
类文件中需要指定所属的包,可以使用package语句。
例如:
package com.example;
public class MyClass {
...
}
这个类MyClass位于com.example包中。
2.2.12 IO流
Java中的IO流用于在程序和文件之间进行数据传输。在Java中,可以使用InputStream、OutputStream、Reader和Writer等类来实现IO操作。
例如:
File file = new File("example.txt");
try (FileReader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
这段代码中,使用FileReader和BufferedReader读取一个文本文件的内容并输出。try-with-resources语句可以自动关闭IO流。
2.2.13 注解
注解是Java中的一种元数据,用于为程序元素(类、方法、变量等)添加额外的信息。注解以@开头,可以应用于声明、类型、方法等各种程序元素。
例如:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String author() default "binjie09";
String date();
}
这个注解定义了一个@MyAnnotation注解,包含了两个属性author和date。
在程序中使用注解,例如:
@MyAnnotation(date = "2023-04-17")
public void myMethod() {
System.out.println("这是一个带有注解的方法。");
}
这个方法使用了@MyAnnotation注解,并指定了date属性的值。
2.2.14 泛型
泛型是一种Java中的类型安全机制,它可以将类或方法中操作的数据类型作为参数来指定。在使用泛型时,可以避免类型转换的错误和代码的冗长。
例如,定义一个泛型类:
public class MyList<T> {
private T[] elements;
private int size;
public MyList(int capacity) {
this.elements = (T[]) new Object[capacity];
this.size = 0;
}
public void add(T element) {
this.elements[size++] = element;
}
public T get(int index) {
return elements[index];
}
public int size() {
return size;
}
}
这个MyList类实现了一个简单的列表,使用泛型参数T来指定列表中元素的类型。
使用这个泛型类,例如:
MyList<Integer> myList = new MyList<>(10);
myList.add(1);
myList.add(2);
myList.add(3);
for (int i = 0; i < myList.size(); i++) {
System.out.println(myList.get(i));
}
这个例子中,创建了一个能够存储整数的MyList对象,并向其中添加了三个元素。
2.2.15 枚举
枚举是Java中的一种特殊数据类型,它限定了某个变量只能取某些固定的值。在Java中,可以使用enum关键字定义一个枚举。
例如:
public enum MyEnum {
APPLE,
BANANA,
ORANGE
}
这个MyEnum枚举定义了三个固定的值:APPLE、BANANA和ORANGE。
在程序中使用枚举,例如:
MyEnum fruit = MyEnum.BANANA;
switch (fruit) {
case APPLE:
System.out.println("这是一个苹果。");
break;
case BANANA:
System.out.println("这是一个香蕉。");
break;
case ORANGE:
System.out.println("这是一个橘子。");
break;
}
这个例子中,使用枚举定义一个水果类型,并根据不同的水果类型输出不同的信息。
2.2.16 Lambda表达式
Lambda表达式是Java 8中新增的一种语法,它可以将一个匿名函数作为参数传递给方法或者直接作为返回值返回。
Lambda表达式的格式是:
(parameters) -> expression
或
(parameters) -> { statements; }
例如:
List<Integer> myList = new ArrayList<>();
myList.add(1);
myList.add(2);
myList.add(3);
myList.forEach(n -> System.out.println(n));
这个例子中,使用Lambda表达式打印了一个列表中的所有元素。
2.2.17 Stream API
Stream API是Java 8中新增的一组API,用于对集合、数组等进行各种操作。Stream可以很方便地实现筛选、排序、映射等操作,简化了代码的编写。
例如:
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
这个例子中,使用Stream API实现了对一个列表进行筛选、映射、排序和打印。
2.2.18 时间日期
在Java 8之前,处理日期和时间是繁琐而且容易出错的。而在Java 8中,引入了java.time包,提供了一组全新的API来解决这个问题,使得处理日期和时间变得更加容易和直观。
例如:
LocalDateTime now = LocalDateTime.now();
System.out.println("现在的时间是:" + now);
这个例子中,使用LocalDateTime类获取当前本地日期和时间,并将其打印出来。
2.2.19 异常处理
在Java中,异常是指程序运行时可能会发生的非预期事件,例如除以0、访问空指针对象等。为了使程序在发生异常时能够正常运行,需要使用异常处理机制。
在Java中,异常是通过try-catch块来处理的。try块中包含可能会抛出异常的代码,而catch块用于捕获并处理异常。
例如:
try {
int result = 1 / 0;
} catch (ArithmeticException e) {
System.out.println("除数不能为0!");
}
这个例子中,尝试进行一次除法运算,由于分母为0,会抛出一个ArithmeticException异常。在catch块中捕获并处理这个异常,并将错误信息打印出来。
- 正则表达式
正则表达式是一种用于匹配字符串的模式,它可以用来进行字符串的查找、匹配、替换等操作。在Java中,可以使用java.util.regex包中的类来实现正则表达式的功能。
例如:
String input = "I have 2 apples and 3 oranges.";
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
System.out.println(matcher.group());
}
这个例子中,使用正则表达式查找一个字符串中的数字,并将其打印出来。
2.2.20 多线程
在Java中,多线程是一种同时执行多个任务的机制,可以提高程序的并发性和效率。Java中的多线程实现是基于线程对象的,可以使用java.lang.Thread类或者java.util.concurrent包中的类来创建和管理线程。
例如:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程名称:" + Thread.currentThread().getName());
}
}
public class MultiThreadTest {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
}
这个例子中,创建了一个MyRunnable类实现了Runnable接口,并重写了run()方法。在MultiThreadTest类中,创建了5个线程,并启动它们执行MyRunnable中定义的任务,每个线程输出自己的名称。
2.2.21 注解
在Java中,注解是用来标记代码的一种方式,可以帮助开发者在编写代码时提供更多的信息。Java中的注解是利用@符号来定义的,可以应用在类、方法、变量等各种地方。
例如:
@Deprecated
public class OldClass {
// ...
}
public class NewClass {
@SuppressWarnings("unchecked")
public void myMethod() {
// ...
}
}
这个例子中,使用了@Deprecated和@SuppressWarnings两个注解。@Deprecated表示某个类或方法已经过时,不建议使用;@SuppressWarnings表示忽略一些警告信息。
2.2.22 反射
反射(Reflection)是指在程序运行时动态地获取类信息、调用对象方法或创建对象实例的能力。在Java中,可以使用java.lang.reflect包中的类来实现反射功能。
例如:
Class<?> clazz = Class.forName("com.example.MyClass");
Object instance = clazz.newInstance();
Method method = clazz.getMethod("myMethod");
method.invoke(instance);
这个例子中,使用Class.forName()方法通过类名获取MyClass类的Class对象;使用newInstance()方法创建MyClass的实例对象;使用getMethod()方法获取MyClass对象的myMethod()方法;使用invoke()方法调用myMethod方法。
2.2.23 IO流
在Java中,I/O流(输入/输出流)用于读取和写入数据。Java中的IO流分为字节流和字符流,以及输入流和输出流。可以使用java.io包中的类来实现I/O操作。
例如:
try (
FileReader fileReader = new FileReader("example.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
) {
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
这个例子中,创建了一个FileReader对象和一个BufferedReader对象,用于读取example.txt文件中的内容,并将其打印出来。
2.2.24 泛型
在Java中,泛型是一种参数化类型的机制,可以使代码更加通用、安全和可读。可以使用<>符号来定义泛型。
例如:
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
for (String s : list) {
System.out.println(s);
}
这个例子中,创建了一个List
2.2.25 枚举
枚举(Enumeration)是指将一组相关的常量定义为一个特殊的数据类型来使用。在Java中,可以使用enum关键字来定义枚举类型。
例如:
public enum Color {
RED, GREEN, BLUE;
}
public class MyClass {
public static void main(String[] args) {
Color c = Color.RED;
System.out.println(c);
}
}
这个例子中,定义了一个Color枚举类型,包含三个常量:RED、GREEN、BLUE。在MyClass类的main()方法中,定义了一个Color类型的变量,并将其赋值为RED,然后将其输出。
2.2.26 Lambda表达式
Lambda表达式是一种函数式编程的语法,可以简化代码结构,使代码更加简洁、易读。在Java 8中,引入了Lambda表达式的机制。
例如:
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.forEach((s) -> System.out.println(s));
这个例子中,使用Lambda表达式遍历一个字符串类型的集合对象,并将集合中的元素打印出来。
- Stream流
Stream是一种数据流的处理方式,可以用于对集合、数组等数据进行多种操作(如过滤、排序、统计等),以实现更高效、更简洁的代码。
例如:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "melon");
long count = list.stream().filter(s -> s.length() > 5).count();
System.out.println("长度大于5的字符串个数为:" + count);
这个例子中,创建了一个包含5个元素的字符串类型的List对象,使用Stream流的filter()方法筛选出字符串长度大于5的元素,并使用count()方法统计筛选后的元素个数。
2.2.27 Optional
Optional是一种容器对象,可以用于处理null值。在Java 8中,引入了Optional类,可以避免代码中出现null值的问题。
例如:
Optional<String> optional = Optional.ofNullable(null);
String value = optional.orElse("default value");
System.out.println(value);
这个例子中,创建了一个Optional容器对象,其值为null,然后使用orElse()方法指定默认值,最后将其输出。