static关键字是Java中的一个关键字,它可以用来修饰类的成员变量、成员方法和内部类。static修饰的成员变量和成员方法属于类本身,而不是类的实例,因此它们在类加载时就被初始化,并且在类卸载时被销毁。static修饰的成员变量和成员方法可以被类的所有实例共享,并且可以通过类名直接访问。 static关键字的使用场景包括: * 定义类的常量。 * 定义类的静态方法。 * 定义类的静态内部类。 static关键字的使用需要注意以下几点: * static修饰的成员变量和成员方法不能直接访问非static成员变量和成员方法。 * static修饰的成员变量和成员方法不能直接访问this指针。 * static修饰的成员变量和成员方法不能直接调用非static方法。 static关键字在Java中是一个非常重要的关键字,它可以用来实现很多功能。在使用static关键字时,需要注意以上几点,以避免出现错误。 以下是static关键字的使用示例:
public class Person { private String name; private int age; public static String getName() { return name; } public static void setName(String name) { Person.name = name; } public static int getAge() { return age; } public static void setAge(int age) { Person.age = age; } public static void main(String[] args) { System.out.println(Person.getName()); Person.setName("张三"); System.out.println(Person.getName()); } }
在以上示例中,我们定义了一个Person类,并使用static关键字修饰了name和age两个成员变量。name和age两个成员变量是类的常量,它们在类加载时就被初始化,并且在类卸载时被销毁。我们还定义了两个静态方法getName()和setName(),这两个方法可以直接通过类名访问。在main()方法中,我们通过Person.getName()方法获取了Person类的name成员变量的值,并通过Person.setName()方法设置了Person类的name成员变量的值。 static关键字在Java中是一个非常重要的关键字,它可以用来实现很多功能。在使用static关键字时,需要注意以上几点,以避免出现错误。
二.封装
Java的封装(Encapsulation)是面向对象编程的一种特性,它将数据(成员变量)和操作(方法)封装在一个类中,并对外提供公共的接口来访问和操作这些数据。封装的目的是隐藏类的内部实现细节,同时提供一种安全的方式来访问和修改类的数据。 封装的主要概念包括: 1. 成员变量的私有化:将类的成员变量声明为私有(private),这样外部代码无法直接访问和修改这些变量。私有化成员变量可以有效地防止外部代码直接对数据进行修改,从而保证数据的安全性。 2. 公共的访问方法:通过公共的访问方法(getter和setter方法)来控制对成员变量的访问和修改。公共的访问方法提供了一种安全的方式来读取和修改成员变量的值,并且可以在方法中添加必要的逻辑和验证来保证数据的有效性。 封装的优点包括: 1. 数据隐藏:封装可以隐藏类的内部实现细节,只暴露必要的接口给外部使用,这样可以提高代码的安全性和可维护性。 2. 代码复用:封装可以将类的内部实现细节封装起来,使得类的使用者只关注接口的使用,而不需要关心内部的具体实现。这样可以提高代码的复用性,降低代码的耦合性。 3. 灵活性:封装可以使类的内部实现细节可以自由地修改,而不会影响到外部代码的使用。这样可以提供更好的灵活性,使得代码可以更容易地进行扩展和修改。 使用封装的示例:
public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { if (age >= 0) { this.age = age; } else { System.out.println("年龄不能为负数"); } } }
在上面的示例中,Person类封装了name和age两个成员变量,并提供了公共的访问方法getName()和setName()来访问和修改这些成员变量。在setAge()方法中,添加了对年龄的验证,确保年龄不会为负数。 通过封装,外部代码可以通过公共的访问方法来访问和修改Person对象的数据,而无需直接操作成员变量。这样可以保证数据的安全性,并且可以在访问方法中添加逻辑和验证,保证数据的有效性
三.继承
Java的继承(Inheritance)是面向对象编程的一种特性,它允许一个类从另一个类中继承属性和方法。继承可以提高代码的复用性,降低代码的维护成本。 继承的语法如下:
class 子类 extends 父类 { // 子类的成员变量和方法 }
在以上语法中,子类继承了父类的所有成员变量和方法,包括私有成员变量和方法。子类也可以定义自己的成员变量和方法。 继承的优点包括: * 提高代码的复用性。 * 降低代码的维护成本。 * 实现代码的扩展。 * 实现代码的重用。 继承的缺点包括: * 子类可能会继承父类的错误。 * 子类可能会继承父类的缺陷。 * 子类可能会继承父类的冗余代码。 继承的应用场景包括: * 实现代码的扩展。 * 实现代码的重用。 * 实现代码的复用。 继承的注意事项包括: * 子类不能继承父类的私有成员变量和方法。 * 子类可以继承父类的受保护成员变量和方法。 * 子类可以继承父类的公共成员变量和方法。 以下是一个继承的示例:
class Person { private String name; private int age; 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; } } class Student extends Person { private String school; public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } }
在以上示例中,Student类继承了Person类的所有成员变量和方法。Student类还定义了自己的成员变量school。 通过继承,Student类可以直接使用Person类的所有成员变量和方法。例如,Student类可以直接使用Person类的getName()方法和setName()方法来获取和设置学生的姓名。Student类也可以直接使用Person类的getAge()方法和setAge()方法来获取和设置学生的年龄。 此外,Student类还可以定义自己的成员变量school。例如,Student类可以定义一个字符串类型的成员变量school,用于表示学生就读的学校。 通过继承,Student类可以实现代码的复用和扩展。Student类可以直接使用Person类的所有成员变量和方法,同时还可以定义自己的成员变量school。这样,Student类可以实现代码的复用和扩展。
四.多态
Java的多态(Polymorphism)是面向对象编程的一种特性,它允许一个变量引用具有不同类型的对象。多态可以提高代码的灵活性和可扩展性。 多态的语法如下:
class A { // 方法 } class B extends A { // 方法 } class C extends A { // 方法 } public class Test { public static void main(String[] args) { A a = new B(); a.method(); } }
在以上代码中,变量a是一个A类型的变量,但是它可以引用一个B类型的对象。当调用a.method()方法时,会调用B类型的method()方法。 多态的优点包括: * 提高代码的灵活性。 * 提高代码的可扩展性。 * 减少代码的重复。 多态的缺点包括: * 可能会导致运行时错误。 * 可能会导致代码难以理解。 多态的应用场景包括: * 实现抽象类。 * 实现接口。 * 实现继承。 多态的注意事项包括: * 多态需要在编译时进行类型检查。 * 多态需要在运行时进行类型转换。 * 多态可能会导致运行时错误。 以下是一个多态的示例:
class Animal { public void eat() { System.out.println("动物吃东西"); } } class Dog extends Animal { public void eat() { System.out.println("狗吃骨头"); } } class Cat extends Animal { public void eat() { System.out.println("猫吃鱼"); } } public class Test { public static void main(String[] args) { Animal a = new Dog(); a.eat(); a = new Cat(); a.eat(); } }
在以上代码中,变量a是一个Animal类型的变量,但是它可以引用一个Dog类型的对象和一个Cat类型的对象。当调用a.eat()方法时,会调用Dog类型的eat()方法和Cat类型的eat()方法。 多态可以提高代码的灵活性和可扩展性。在以上代码中,我们可以通过创建不同的Animal类型的对象来实现不同的功能。当我们需要增加新的Animal类型的对象时,我们只需要修改Animal类型的eat()方法,而不需要修改其他代
五、final关键字
Java中的final关键字可以用来修饰变量、方法和类。 * 修饰变量时,表示该变量不可变。 * 修饰方法时,表示该方法不可被重写。 * 修饰类时,表示该类不可被继承。 final关键字可以用来提高程序的安全性和可维护性。 * 修饰变量时,可以防止该变量被意外修改,从而提高程序的安全性。 * 修饰方法时,可以防止该方法被意外重写,从而提高程序的可维护性。 * 修饰类时,可以防止该类被意外继承,从而提高程序的安全性和可维护性。 以下是final关键字的使用示例
// 修饰变量 final int MAX_VALUE = 100; // 修饰方法 public final void doSomething() { // 方法体 } // 修饰类 public final class MyClass { // 类体 }
六、抽象
Java中的抽象(abstraction)是一种面向对象编程的特性,它可以通过抽象类和接口来实现。 抽象类(abstract class)是用关键字abstract声明的类,它不能被实例化,只能被继承。抽象类可以包含抽象方法和非抽象方法。抽象方法(abstract method)是没有具体实现的方法,只有方法的声明,没有方法体。子类继承抽象类时,必须实现抽象类中的所有抽象方法。 以下是抽象类的示例:
abstract class Animal { // 抽象方法 public abstract void makeSound(); // 非抽象方法 public void sleep() { System.out.println("Animal is sleeping"); } } class Dog extends Animal { public void makeSound() { System.out.println("Dog barks"); } } public class Main { public static void main(String[] args) { Animal dog = new Dog(); dog.makeSound(); // 输出 "Dog barks" dog.sleep(); // 输出 "Animal is sleeping" } }
接口(interface)是一种完全抽象的类,它只包含抽象方法和常量。接口中的方法默认是公共的抽象方法,常量默认是公共的静态常量。类通过实现(implements)接口来使用接口定义的方法和常量。 以下是接口的示例:
interface Animal { // 抽象方法 void makeSound(); // 默认方法 default void sleep() { System.out.println("Animal is sleeping"); } } class Dog implements Animal { public void makeSound() { System.out.println("Dog barks"); } } public class Main { public static void main(String[] args) { Animal dog = new Dog(); dog.makeSound(); // 输出 "Dog barks" dog.sleep(); // 输出 "Animal is sleeping" } }
抽象类和接口都是用来实现抽象化的概念,通过它们可以定义规范和共享行为。抽象类适用于具有共同行为和属性的类的继承关系,而接口适用于不同类具有相同行为的情况。
七、接口
Java中的接口(Interface)是一种完全抽象的类,它只包含抽象方法和常量的定义。接口定义了一组方法的规范,而不涉及方法的具体实现。 接口使用 interface
关键字来声明,其中可以包含抽象方法、默认方法、静态方法和常量。类通过实现(implements)接口来使用接口定义的方法和常量。 以下是接口的示例:
interface Animal { // 抽象方法 void makeSound(); // 默认方法 default void sleep() { System.out.println("Animal is sleeping"); } // 静态方法 static void run() { System.out.println("Animal is running"); } // 常量 int LEGS = 4; } class Dog implements Animal { public void makeSound() { System.out.println("Dog barks"); } } public class Main { public static void main(String[] args) { Animal dog = new Dog(); dog.makeSound(); // 输出 "Dog barks" dog.sleep(); // 输出 "Animal is sleeping" Animal.run(); // 输出 "Animal is running" System.out.println(Animal.LEGS); // 输出 "4" } }
在上面的示例中, Animal
接口定义了 makeSound()
抽象方法, sleep()
默认方法, run()
静态方法和 LEGS
常量。类 Dog
通过实现 Animal
接口来使用这些方法和常量。
八、内部类
Java中的内部类(Inner Class)是定义在另一个类内部的类。内部类可以访问外部类的所有成员,包括私有成员。内部类可以分为成员内部类和局部内部类。 * 成员内部类:成员内部类是定义在外部类的成员位置(比如成员变量、成员方法、构造方法)上的内部类。成员内部类可以访问外部类的所有成员,包括私有成员。 * 局部内部类:局部内部类是定义在外部类的方法、构造方法或代码块中的内部类。局部内部类只能访问外部类的局部变量和方法,不能访问外部类的私有成员。 内部类可以用来实现以下功能: * 封装:内部类可以将外部类的某些成员隐藏起来,以提高代码的安全性。 * 继承:内部类可以继承外部类,也可以继承其他类。 * 多重继承:内部类可以同时继承多个外部类。 * 访问私有成员:内部类可以访问外部类的私有成员。 内部类的使用可以提高代码的复用性和可维护性
九、异常
Java中的异常(Exception)是一种不正常的事件,它会导致程序中断。异常可以分为两种:编译时异常和运行时异常。 * 编译时异常:编译时异常是必须在编译时处理的异常,否则程序无法编译通过。例如,数组越界异常和空指针异常。 * 运行时异常:运行时异常是可以选择在运行时处理的异常,如果不处理,程序会继续运行,但可能会出现错误。例如,文件读写异常和网络连接异常。 异常可以通过try-catch语句来捕获和处理。try-catch语句的语法如下:
try { // 可能发生异常的代码 } catch (Exception e) { // 异常处理代码 }
如果try语句块中发生了异常,那么catch语句块中的代码就会被执行。catch语句块中的代码可以捕获和处理异常。 异常也可以通过throw语句来抛出。throw语句的语法如下:
throw new Exception("异常信息");
throw语句可以将异常抛给调用者。调用者可以捕获和处理异常,也可以继续抛出异常。 异常的使用可以提高程序的健壮性。通过捕获和处理异常,可以避免程序中断,并保证程序的正常运行。
十、集合概述和分类
Java集合(Collection)是用来存储一组对象的容器。集合可以分为两大类:有序集合和无序集合。
* 有序集合:有序集合中的元素是有序的,可以通过索引访问元素。有序集合包括List和Queue。
* 无序集合:无序集合中的元素是无序的,不能通过索引访问元素。无序集合包括Set和Map。
List是Java中常用的有序集合,它可以存储重复元素。List有两种实现类:ArrayList和LinkedList。ArrayList是基于数组实现的,LinkedList是基于链表实现的。
Queue是Java中常用的无序集合,它可以存储元素并按照先进先出(FIFO)的顺序访问元素。Queue有两种实现类:PriorityQueue和ArrayDeque。PriorityQueue是基于优先队列实现的,ArrayDeque是基于双端队列实现的。
Set是Java中常用的无序集合,它不能存储重复元素。Set有两种实现类:HashSet和TreeSet。HashSet是基于哈希表实现的,TreeSet是基于二叉树实现的。
Map是Java中常用的无序集合,它可以存储键值对。Map有两种实现类:HashMap和TreeMap。HashMap是基于哈希表实现的,TreeMap是基于二叉树实现的。
以下是Java集合的分类:
| 集合类型 | 实现类 | 特点 |
|---|---|---|
| 有序集合 | List | 元素是有序的,可以通过索引访问元素 |
| 无序集合 | Set | 元素是无序的,不能通过索引访问元素 |
| List | ArrayList | 基于数组实现,元素可以随机访问 |
| List | LinkedList | 基于链表实现,元素只能从头尾两端访问 |
| Queue | PriorityQueue | 基于优先队列实现,元素按照优先级访问 |
| Queue | ArrayDeque | 基于双端队列实现,元素可以从头尾两端访问 |
| Set | HashSet | 基于哈希表实现,元素不能重复 |
| Set | TreeSet | 基于二叉树实现,元素按照顺序访问 |
| Map | HashMap | 基于哈希表实现,元素可以随机访问 |
| Map | TreeMap | 基于二叉树实现,元素按照顺序访问 |
十一、Collection遍历方式
Java集合遍历方式有以下几种:
* 迭代器遍历
* 增强for循环
* 普通for循环
* 列表迭代器
* 集合迭代器
迭代器遍历是使用迭代器对象来遍历集合中的元素。迭代器对象是集合接口的内部类,它提供了next()和hasNext()方法来遍历集合中的元素。
增强for循环是使用增强for循环语句来遍历集合中的元素。增强for循环语句的语法如下:
for (元素类型 元素变量 : 集合对象) {
// 对元素变量进行操作
}
普通for循环是使用普通for循环语句来遍历集合中的元素。普通for循环语句的语法如下:
for (int i = 0; i < 集合对象.size(); i++) {
// 对集合对象的元素进行操作
}
列表迭代器是使用列表迭代器对象来遍历列表中的元素。列表迭代器对象是List接口的内部类,它提供了next()和hasNext()方法来遍历列表中的元素。
集合迭代器是使用集合迭代器对象来遍历集合中的元素。集合迭代器对象是Collection接口的内部类,它提供了next()和hasNext()方法来遍历集合中的元素。
以下是使用迭代器遍历集合中的元素的示例代码:
import java.util.ArrayList;
import java.util.Iterator;
public class IteratorDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// 使用迭代器遍历集合
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
}
}
以下是使用增强for循环遍历集合中的元素的示例代码:
import java.util.ArrayList;
public class EnhancedForDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// 使用增强for循环遍历集合
for (String element : list) {
System.out.println(element);
}
}
}
以下是使用普通for循环遍历集合中的元素的示例代码:
import java.util.ArrayList;
public class ForDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// 使用普通for循环遍历集合
for (int i = 0; i < list.size(); i++) {
String element = list.get(i);
System.out.println(element);
}
}
}
以下是使用列表迭代器遍历列表中的元素的示例代码:
import java.util.ArrayList;
import java.util.ListIterator;
public class ListIteratorDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// 使用列表迭代器遍历列表
ListIterator<String> iterator = list.listIterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
}
}
十二、List系列集合
List是Java中常用的有序集合,它可以存储重复元素。List有两种实现类:ArrayList和LinkedList。ArrayList是基于数组实现的,LinkedList是基于链表实现的。
ArrayList的特点是元素可以随机访问,但插入和删除元素的效率较低。LinkedList的特点是插入和删除元素的效率较高,但元素不能随机访问。
以下是List系列集合的常用方法:
* add(E e):向集合中添加元素。
* remove(E e):从集合中删除元素。
* get(int index):获取集合中指定位置的元素。
* set(int index, E e):将集合中指定位置的元素替换为另一个元素。
* isEmpty():判断集合是否为空。
* size():获取集合中元素的个数。
* iterator():返回一个迭代器对象,用于遍历集合中的元素。
以下是List系列集合的使用示例:
import java.util.ArrayList;
public class ListDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// 向集合中添加元素
list.add("d");
// 从集合中删除元素
list.remove("a");
// 获取集合中指定位置的元素
String element = list.get(1);
// 将集合中指定位置的元素替换为另一个元素
list.set(1, "e");
// 判断集合是否为空
boolean isEmpty = list.isEmpty();
// 获取集合中元素的个数
int size = list.size();
// 遍历集合中的元素
for (String e : list) {
System.out.println(e);
}
}
}
List系列集合是Java中常用的集合类型,它可以满足很多场景下的集合需求。在使用List系列集合时,需要根据具体的场景选择合适的实现类。