Java基础学习资料
一、Java简介
Java是一种广泛使用的高级编程语言,它具有简单性、面向对象、分布式、健壮性、安全性、平台独立性与可移植性、多线程等诸多特性。Java程序可以运行在不同的操作系统上,这得益于Java虚拟机(JVM)的存在。
Java的发展历程可以追溯到上世纪90年代,由Sun Microsystems公司(现在归属于Oracle公司)开发。从最初的Java 1.0版本不断演进,如今已经发展到Java 17等较新版本,每个版本都在性能、功能和安全性方面有所提升。
二、环境搭建
- 安装JDK(Java Development Kit)
- 首先,需要从Oracle官方网站或者其他可靠来源(如AdoptOpenJDK)下载适合自己操作系统的JDK版本。对于Windows系统,可以下载.exe安装文件;对于Linux系统,可以下载相应的.rpm或者.deb包,或者直接使用命令行安装(如在Ubuntu系统中,可以使用apt - get命令);对于Mac系统,可以下载.dmg文件。
- 在Windows系统中,运行安装文件,按照提示进行安装。安装过程中需要注意设置环境变量,将JDK的安装目录下的bin文件夹路径添加到系统的PATH环境变量中,这样就可以在命令行中方便地使用Java相关命令。
- 验证安装
- 在命令行(Windows系统中的命令提示符或者Linux/Mac系统中的终端)中输入“java - version”命令,如果安装成功,将会显示Java的版本信息。
三、Java基础语法
-
数据类型
- 基本数据类型
- 整数类型:byte(8位有符号整数,取值范围为 - 128到127)、short(16位有符号整数,取值范围为 - 32768到32767)、int(32位有符号整数,取值范围为 - 2147483648到2147483647)、long(64位有符号整数,取值范围为 - 9223372036854775808到9223372036854775807,在定义长整型常量时,需要在数字后面加上“L”或者“l”,例如123L)。
- 浮点类型:float(32位单精度浮点数,在定义单精度浮点数常量时,需要在数字后面加上“F”或者“f”,例如3.14F)、double(64位双精度浮点数,例如3.14159)。
- 字符类型:char(16位无符号Unicode字符,用单引号括起来,例如'c')。
- 布尔类型:boolean(只有true和false两个值)。
- 引用数据类型
- 类(class):例如自定义的类,以及Java标准库中的类如String。
- 接口(interface)。
- 数组(array)。
- 基本数据类型
-
变量与常量
- 变量
- 在Java中,变量需要先声明后使用。声明变量的格式为:数据类型 变量名;例如:int num;。然后可以对变量进行赋值,如num = 10;也可以在声明变量的同时进行赋值,如int num = 10;。
- 变量的命名规则:变量名只能包含字母、数字、下划线和美元符号;变量名不能以数字开头;变量名不能是Java中的关键字(如if、else、for等);变量名要有意义,遵循驼峰命名法(例如firstName)。
- 常量
- 在Java中,可以使用final关键字来定义常量。例如:final int MAX_VALUE = 100;一旦常量被赋值,就不能再修改。
- 变量
-
运算符
- 算术运算符:+(加法)、 - (减法)、*(乘法)、/(除法)、%(取余)。例如:int a = 10; int b = 3; int sum=a + b; //sum的值为13,int div=a / b; //div的值为3,int mod=a%b; //mod的值为1。
- 关系运算符:==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)。例如:int x = 5; int y = 3; boolean result=(x > y); //result的值为true。
- 逻辑运算符:&&(逻辑与)、||(逻辑或)、!(逻辑非)。例如:boolean a = true; boolean b = false; boolean c=a&&b; //c的值为false,boolean d=a||b; //d的值为true,boolean e =!a; //e的值为false。
- 位运算符:&(按位与)、|(按位或)、^(按位异或)、~(按位取反)、<<(左移)、>>(右移)、>>>(无符号右移)。例如:int num1 = 3; //二进制为0011,int num2 = 5; //二进制为0101,int result1 = num1&num2; //结果为1(二进制0001)。
- 赋值运算符:=(简单赋值)、+=(加后赋值)、- =(减后赋值)、* =(乘后赋值)、/ =(除后赋值)、% =(取余后赋值)。例如:int m = 10; m+=5; //相当于m = m + 5,此时m的值为15。
-
控制语句
- 顺序结构
- 在Java中,顺序结构是最基本的结构,代码按照书写的顺序依次执行。例如: public class Main { public static void main(String[] args) { int a = 10; int b = 20; int sum=a + b; System.out.println("a + b的结果为:" + sum); } }
- 选择结构
- if - else语句
- 基本形式为:if(条件表达式){//条件表达式为真时执行的语句} else {//条件表达式为假时执行的语句}。例如: public class Main { public static void main(String[] args) { int num = 10; if(num > 5){ System.out.println("num大于5"); } else { System.out.println("num小于等于5"); } } }
- switch - case语句
- 用于多分支选择,格式为:switch(表达式){case常量表达式1:语句1;break;case常量表达式2:语句2;break;...default:语句n;break;}。表达式的值必须是byte、short、int、char或者枚举类型(Java 5.0及以上版本)、String类型(Java 7.0及以上版本)。例如: public class Main { public static void main(String[] args) { int day = 3; switch(day){ case 1: System.out.println("星期一"); break; case 2: System.out.println("星期二"); break; case 3: System.out.println("星期三"); break; default: System.out.println("其他"); break; } } }
- if - else语句
- 循环结构
- for循环
- 基本格式为:for(初始化表达式;条件表达式;更新表达式){循环体语句}。例如: public class Main { public static void main(String[] args) { for(int i = 0; i < 5; i++){ System.out.println("i的值为:" + i); } } }
- while循环
- 格式为:while(条件表达式){循环体语句}。例如: public class Main { public static void main(String[] args) { int i = 0; while(i < 5){ System.out.println("i的值为:" + i); i++; } } }
- do - while循环
- 格式为:do{循环体语句}while(条件表达式);。与while循环的区别是,do - while循环先执行一次循环体,再判断条件表达式。例如: public class Main { public static void main(String[] args) { int i = 0; do{ System.out.println("i的值为:" + i); i++; }while(i < 5); } }
- for循环
- 顺序结构
四、数组
-
数组的定义与初始化
- 定义数组:数据类型[] 数组名;例如:int[] arr;。也可以写成数据类型 数组名[];例如:int arr[];(不过这种写法不太推荐)。
- 初始化数组
- 静态初始化:在定义数组的同时就指定数组元素的值。例如:int[] arr={1, 2, 3};
- 动态初始化:先定义数组,然后再为数组元素赋值。例如:int[] arr = new int;//创建一个长度为3的整型数组,然后可以通过arr=1;arr=2;arr=3;来赋值。
-
数组的访问与遍历
- 访问数组元素:通过数组名和下标来访问数组元素,下标从0开始。例如:int[] arr={1, 2, 3};int num = arr;//num的值为1。
- 遍历数组
- 使用for循环遍历数组: public class Main { public static void main(String[] args) { int[] arr={1, 2, 3}; for(int i = 0; i < arr.length; i++){ System.out.println("arr["+i+"]的值为:" + arr[i]); } } }
- 使用增强for循环(for - each循环,适用于Java 5.0及以上版本)遍历数组: public class Main { public static void main(String[] args) { int[] arr={1, 2, 3}; for(int num : arr){ System.out.println("数组元素的值为:" + num); } } }
-
二维数组
- 定义二维数组:数据类型[][] 数组名;例如:int[][] arr;。
- 初始化二维数组
- 静态初始化:int[][] arr ={{1, 2, 3},{4, 5, 6}};
- 动态初始化:int[][] arr = new int;//创建一个2行3列的二维数组。
- 访问和遍历二维数组
- 访问二维数组元素:int[][] arr ={{1, 2, 3},{4, 5, 6}};int num = arr;//num的值为1。
- 遍历二维数组: public class Main { public static void main(String[] args) { int[][] arr ={{1, 2, 3},{4, 5, 6}}; for(int i = 0; i < arr.length; i++){ for(int j = 0; j < arr[i].length; j++){ System.out.println("arr["+i+"] ["+j+"]的值为:" + arr[i][j]); } } } }
五、类与对象
-
类的定义
- 在Java中,类是一种数据结构,用于封装数据和方法。类的定义格式为: public class ClassName { //类的成员变量 private int age; private String name; //类的构造函数 public ClassName(int age, String name) { this.age = age; this.name = name; } //类的成员方法 public int getAge() { return age; } public String getName() { return name; } }
-
对象的创建与使用
- 创建对象:使用new关键字来创建对象。例如:ClassName obj = new ClassName(20, "John");
- 使用对象:通过对象名来访问对象的成员变量和调用成员方法。例如:int age = obj.getAge();String name = obj.getName();
-
构造函数
- 构造函数是一种特殊的方法,用于创建对象时初始化对象的成员变量。构造函数的名称必须与类名相同,并且没有返回类型(包括void)。如果没有显式定义构造函数,Java会自动提供一个默认的构造函数(无参构造函数)。例如: public class MyClass { private int num; public MyClass() { num = 0; } public MyClass(int num) { this.num = num; } }
-
封装、继承与多态
- 封装
- 封装是将数据和操作数据的方法封装在一起,并对外部隐藏实现细节。在Java中,通过使用private关键字来实现封装。例如,将类的成员变量声明为private,然后提供public的get和set方法来访问和修改成员变量。
- 继承
- 继承是一种创建新类(子类)的方式,子类继承父类的属性和方法。在Java中,使用extends关键字来实现继承。例如: public class Animal { public void eat() { System.out.println("动物在吃东西"); } } public class Dog extends Animal { public void bark() { System.out.println("狗在叫"); } }
- 多态
- 多态是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在Java中,多态可以通过方法重写和方法重载来实现。
- 方法重写:在子类中重新定义父类中已经存在的方法,要求方法签名(方法名、参数列表、返回类型)相同。例如: public class Animal { public void move() { System.out.println("动物在移动"); } } public class Bird extends Animal { @Override public void move() { System.out.println("鸟在飞"); } }
- 方法重载:在同一个类中定义多个同名方法,但是参数列表不同(参数个数、参数类型或者参数顺序不同)。例如: public class MathUtils { public int add(int a, int b) { return a + b; } public double add(double a, double b) { return a + b; } }
- 多态是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在Java中,多态可以通过方法重写和方法重载来实现。
- 封装
六、接口与抽象类
- 接口
- 接口是一种特殊的抽象类型,它只包含方法签名和常量。接口的定义格式为: public interface InterfaceName { public static final int CONSTANT = 1; public void method1(); public String method2(); }
- 类实现接口:使用implements关键字来实现接口。一个类可以实现多个接口。例如: public class MyClass implements InterfaceName { @Override public void method1() { System.out.println("实现接口的方法1"); } @Override public String method2() { return "实现接口的方法2的结果"; } }
- 抽象类
- 抽象类是一种不能被实例化的类,它可以包含抽象方法和非抽象方法。抽象方法是一种只有方法签名,没有方法体的方法。抽象类的定义格式为: public abstract class AbstractClass { public abstract void abstractMethod(); public void nonAbstractMethod() { System.out.println("这是一个非抽象方法"); } }
- 子类继承抽象类:子类必须实现抽象类中的所有抽象方法,除非子类也是抽象类。例如: public class SubClass extends AbstractClass { @Override public void abstractMethod() { System.out.println("实现抽象类的抽象方法"); } }
七、异常处理
-
异常的概念
- 在Java中,异常是指程序运行过程中出现的不正常情况。例如,除数为零、数组越界、文件不存在等。Java将异常分为两类:检查异常(Checked Exceptions)和非检查异常(Unchecked Exceptions)。
- 检查异常:是指在编译时就必须处理的异常,例如IOException(文件操作时可能出现的异常)。
- 非检查异常:是指在编译时不需要处理的异常,例如RuntimeException及其子类(如NullPointerException、ArrayIndexOutOfBoundsException等)。
-
异常处理机制
- try - catch语句
- 基本格式为:try{//可能出现异常的代码块}catch(异常类型1异常对象1){//处理异常类型1的代码块}catch(异常类型2异常对象2){//处理异常类型2的代码块}...例如: public class Main { public static void main(String[] args) { try{ int a = 10; int b = 0; int result=a / b; }catch(ArithmeticException e){ System.out.println("除数不能为零:" + e.getMessage()); } } }
- finally语句
- finally语句块中的代码无论是否发生异常都会执行。格式为:
try { // 可能出现异常的代码块 } catch (异常类型1 异常对象1) { // 处理异常类型1的代码块 } catch (异常类型2 异常对象2) { // 处理异常类型2的代码块 }... finally { // 这里的代码总会被执行,例如资源释放操作等 System.out.println("这是finally块中的代码,总会执行"); }
- 自定义异常
- 当Java提供的异常类型不能满足需求时,可以自定义异常。自定义异常需要继承Exception类(如果是检查异常)或者RuntimeException类(如果是非检查异常)。
- 例如,定义一个表示年龄不合法的异常: class IllegalAgeException extends RuntimeException { public IllegalAgeException(String message) { super(message); } }
- 在程序中可以使用这个自定义异常: class Person { private int age; public Person(int age) { if (age < 0) { throw new IllegalAgeException("年龄不能为负数"); } this.age = age; } }
- finally语句块中的代码无论是否发生异常都会执行。格式为:
- try - catch语句
八、输入输出流
- 字节流
字节输入流- InputStream是所有字节输入流的抽象父类。FileInputStream是用于从文件中读取字节的类。例如: try { FileInputStream fis = new FileInputStream("test.txt"); int data; while ((data = fis.read())!= -1) { System.out.print((char) data); } fis.close(); } catch (IOException e) { e.printStackTrace(); }
- 字节输出流
- OutputStream是所有字节输出流的抽象父类。FileOutputStream是用于向文件中写入字节的类。例如: try { FileOutputStream fos = new FileOutputStream("output.txt"); String str = "Hello, World!"; byte[] bytes = str.getBytes(); fos.write(bytes); fos.close(); } catch (IOException e) { e.printStackTrace(); }
- 字符流
字符输入流- Reader是所有字符输入流的抽象父类。FileReader是用于从文件中读取字符的类。例如: try { FileReader fr = new FileReader("test.txt"); int c; while ((c = fr.read())!= -1) { System.out.print((char) c); } fr.close(); } catch (IOException e) { e.printStackTrace(); }
- 字符输出流
- Writer是所有字符输出流的抽象父类。FileWriter是用于向文件中写入字符的类。例如: try { FileWriter fw = new FileWriter("output.txt"); String str = "这是一段写入文件的字符数据"; fw.write(str); fw.close(); } catch (IOException e) { e.printStackTrace(); }
九、多线程
- 线程的概念
- 线程是程序执行流的最小单元。一个进程可以包含多个线程,这些线程可以并发执行。在Java中,线程有两种创建方式:继承Thread类和实现Runnable接口。
- 继承Thread类创建线程
-
- 定义一个类继承Thread类,并重写run方法。例如: class MyThread extends Thread { @Override public void run() { System.out.println("这是一个自定义线程"); } }
- 在主程序中创建并启动线程: public class Main { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); } }
- 实现Runnable接口创建线程
定义一个类实现Runnable接口,实现run方法。例如: class MyRunnable implements Runnable { @Override public void run() { System.out.println("这是通过实现Runnable接口创建的线程"); } }- 在主程序中创建线程并启动: public class Main { public static void main(String[] args) { MyRunnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start(); } }
- 线程的状态
新建(New):线程对象被创建后就处于新建状态。- 就绪(Runnable):当线程对象调用start方法后,线程进入就绪状态,等待CPU资源进行调度。
- 运行(Running):线程获得CPU资源后进入运行状态,执行run方法中的代码。
- 阻塞(Blocked):线程由于某些原因(如等待锁、等待输入输出操作完成等)暂时停止执行,进入阻塞状态。
- 死亡(Dead):线程执行完run方法或者出现异常后,线程进入死亡状态。
- 线程的同步
在多线程环境下,如果多个线程同时访问共享资源,可能会导致数据不一致的问题。为了解决这个问题,可以使用线程同步机制。- 在Java中,可以使用synchronized关键字来实现线程同步。例如: class Counter { private int count = 0; public synchronized void increment() { count++; } public synchronized int getCount() { return count; } }
十、集合框架
- 集合的概念
集合是用于存储和操作一组对象的容器。Java提供了丰富的集合框架,包括List、Set、Map等接口以及它们的实现类。 - List接口
List是有序的集合,可以包含重复元素。ArrayList和LinkedList是List接口的两个常见实现类。- ArrayList
- ArrayList是基于数组实现的动态数组。它的优点是随机访问速度快,缺点是插入和删除元素时效率相对较低。例如: ArrayList<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); list.add("Cherry"); System.out.println(list.get(0));
- LinkedList
- LinkedList是基于链表实现的集合。它的优点是插入和删除元素效率高,缺点是随机访问速度慢。例如: LinkedList<Integer> linkedList = new LinkedList<>(); linkedList.add(1); linkedList.add(2); linkedList.add(3); linkedList.addFirst(0);
- ArrayList
- Set接口
Set是不包含重复元素的集合。HashSet和TreeSet是Set接口的常见实现类。- HashSet
- HashSet是基于哈希表实现的集合。它的元素没有顺序。例如: HashSet<String> set = new HashSet<>(); set.add("Apple"); set.add("Banana"); set.add("Apple"); System.out.println(set.size());
- TreeSet
- TreeSet是基于红黑树实现的集合。它的元素是有序的(默认按照自然顺序或者自定义比较器的顺序)。例如: TreeSet<Integer> treeSet = new TreeSet<>(); treeSet.add(3); treeSet.add(1); treeSet.add(2); for (Integer num : treeSet) { System.out.println(num); }
- HashSet
- Map接口
Map是用于存储键值对的集合。键是唯一的,值可以重复。HashMap和TreeMap是Map接口的常见实现类。- HashMap
- HashMap是基于哈希表实现的Map。它的查找速度快,但是元素没有顺序。例如: HashMap<String, Integer> map = new HashMap<>(); map.put("Apple", 1); map.put("Banana", 2); System.out.println(map.get("Apple"));
- TreeMap
- TreeMap是基于红黑树实现的Map。它的键是有序的。例如: TreeMap<String, Integer> treeMap = new TreeMap<>(); treeMap.put("Cherry", 3); treeMap.put("Apple", 1); treeMap.put("Banana", 2); for (Map.Entry<String, Integer> entry : treeMap.entrySet()) { System.out.println(entry.getKey() + " : " + entry.getValue()); }
- HashMap
Java的基础学习是深入学习Java编程的重要基石。通过掌握上述Java基础内容,包括语法、数据类型、控制语句、数组、类与对象、接口与抽象类、异常处理、输入输出流、多线程和集合框架等,能够为后续学习Java的高级特性、开发大型项目以及深入理解面向对象编程思想奠定坚实的基础。希望这份学习资料对Java初学者有所帮助。