一、Java源文件命名、一个Java文件中可以包含多个Java类
Java源文件的命名规则是与其中的public类名相同,每个Java源文件中只能包含一个public类,且这个public类必须与文件名一致
二、Java特性
1. 简单易学:Java语法与C++类似,但去掉了C++中容易出错的一些特性,使得Java更加易学易用。
2. 面向对象:Java是一种面向对象的编程语言,支持封装、继承和多态等面向对象的特性。
3. 健壮性:Java具有很强的健壮性,能够自动进行内存管理和垃圾回收,有效防止内存泄漏等问题。
4. 安全性:Java提供了安全管理机制,可以防止恶意代码对系统造成破坏。
5. 平台无关性:Java通过虚拟机实现了跨平台性,一次编写,到处运行,可以在不同的操作系统上运行相同的Java程序。
6. 多线程:Java支持多线程编程,可以方便地实现多任务并行执行。
7. 高性能:Java的虚拟机具有即时编译和垃圾回收等优化技术,使得Java程序具有较高的性能。
8. 开发工具丰富:Java有很多优秀的开发工具和框架,如Eclipse、IntelliJ IDEA、Spring等,能够提高开发效率。
9. 社区支持:Java拥有庞大的开发者社区和丰富的第三方库,可以快速获取支持和解决问题。
三、Java的跨平台性
Java程序可以在不同的操作系统和硬件平台上运行,而不需要修改代码。这是因为Java程序在编译时被编译成字节码,而不是特定于某个平台的机器代码。这个字节码可以在任何支持Java虚拟机(JVM)的平台上运行,因此Java程序可以在Windows、Mac、Linux等各种操作系统上运行。
四、数据类型、常量以及标识符
Java的数据类型包括基本数据类型和引用数据类型。基本数据类型包括整数类型(byte、short、int、long)、浮点数类型(float、double)、字符类型(char)和布尔类型(boolean)。引用数据类型包括类、接口、数组等。常量在Java中使用关键字final来定义,一旦被赋值后就不能再改变。常量可以是基本数据类型或引用数据类型,通常使用全大写字母命名。
标识符是用来给变量、方法、类等命名的符号。在Java中,标识符必须以字母、下划线或美元符号开头,后面可以跟字母、数字、下划线或美元符号。标识符区分大小写,长度没有限制。在命名标识符时,通常遵循驼峰命名法,即第一个单词小写,后面每个单词首字母大写。例如:myVariable、myMethod、MyClass。
五、标识符命名、常量特点及使用、数据类型分类、字面量及类型转换
1. 标识符命名规则:
标识符可以包含字母、数字、下划线和美元符号。
标识符不能以数字开头。
标识符区分大小写。
标识符不能使用Java的关键字。
标识符应该具有描述性,易于理解和识别。
2. 常量特点及使用:
常量在Java中使用关键字final来定义,一旦赋值后就不能再改变。
常量通常用全大写字母命名,以便与变量区分。
常量在程序中用于存储不会改变的值,如数学常数、配置参数等。
3. 数据类型分类:
Java的数据类型可以分为基本数据类型和引用数据类型。
基本数据类型包括整数类型(byte、short、int、long)、浮点数类型(float、double)、字符类型(char)和布尔类型(boolean)。
引用数据类型包括类、接口、数组等。
4. 字面量及类型转换:
字面量是代码中直接表示的常量值,如整数、浮点数、字符和布尔值等。
java中的类型转换分为隐式类型转换和显式类型转换。
隐式类型转换是指将数据类型范围小的值赋给数据类型范围大的变量,Java会自动进行类型转换。
显式类型转换是指将数据类型范围大的值赋给数据类型范围小的变量,需要使用强制类型转换符()来进行转换,可能会导致数据丢失或溢出。
六. 字符串的定义和特点(不可变)StringBuffer和StringBuilder
字符串是一组字符的序列,它是不可变的,这意味着一旦创建了一个字符串对象,就不能更改它的内容。StringBuffer和StringBuilder是用来处理可变字符串的类。它们允许对字符串进行修改而不创建新的字符串对象。
StringBuffer是线程安全的,适合在多线程环境下使用,但相对较慢。它的方法都是同步的,保证了多线程情况下的安全性,但会牺牲一些性能。
StringBuilder是非线程安全的,适合在单线程环境下使用,但相对较快。它的方法都是非同步的,因此在单线程环境下可以获得更好的性能表现。
常用方法,如length()、indexOf(char a)、equals(String s)、substring(int beg,int end)、valueOf(int i)等方法
七、字符串转换为整型,整型转换为字符串
在Java中,我们可以使用Integer类的parseInt()方法将字符串转换为整型,例如:
String str = "123";
int num = Integer.parseInt(str);
如果字符串不是一个合法的整数格式,会抛出NumberFormatException异常。
而要将整型转换为字符串,可以使用Integer类的toString()方法,例如:
int num = 123;
String str = Integer.toString(num);
另外,也可以使用String类的valueOf()方法将整型转换为字符串,例如:
int num = 123;
String str = String.valueOf(num);
这两种方法都可以将整型转换为字符串。
八、数组长度,数组中可存储什么样的元素(基本数据类型与引用类型)
在Java中,数组的长度可以通过数组对象的length属性来获取,例如:
int[] arr = new int[5];
int length = arr.length; // 获取数组arr的长度,即5
数组中可以存储不同类型的元素,包括基本数据类型和引用类型。
基本数据类型可以直接存储在数组中,例如:
int[] intArray = new int[5];
intArray[0] = 10;
double[] doubleArray = new double[5];
doubleArray[1] = 3.14;
char[] charArray = new char[5];
charArray[2] = 'a';
引用类型的元素则是存储对对象的引用,例如:
String[] stringArray = new String[5];
stringArray[0] = "hello";
Object[] objectArray = new Object[5];
objectArray[1] = new Object();
这样,数组可以存储不同类型的元素,包括基本数据类型和引用类型。
九、四种访问控制符的使用方法和作用范围
Java中,有四种访问控制符,分别是public、protected、default(包级别,默认)和private。它们可以用来控制类、成员变量和方法的访问权限。
1. 修饰类的访问控制符:
public:表示该类可以被任何其他类访问。
默认(包级别,默认):如果没有指定访问控制符,则表示该类只能被同一个包中的其他类访问。
2. 修饰成员变量和方法的访问控制符:
public:表示该成员变量或方法可以被任何其他类访问。
protected:表示该成员变量或方法可以被同一个包中的其他类访问,并且可以被不同包中的子类访问。
默认(包级别,默认):如果没有指定访问控制符,则表示该成员变量或方法只能被同一个包中的其他类访问。
private:表示该成员变量或方法只能被同一个类中的其他方法访问,不能被其他类访问。
访问控制符的作用范围:
public:在任何地方都可以访问。
protected:同一个包中的类和不同包中的子类可以访问。
默认(包级别,默认):同一个包中的类可以访问。
private:只能在同一个类中访问。
注意,访问控制符不能修饰局部变量,因为局部变量的作用范围仅限于定义它的方法或代码块内部,不需要访问控制符来限制其访问范围。
十.构造方法概念、特点、作用
构造方法是一种特殊的方法,用于在创建对象时进行初始化操作。它的特点包括:
1. 构造方法的名称必须与类名相同。
2. 构造方法没有返回类型,包括void。
3. 构造方法可以有参数,也可以没有参数。
4. 构造方法在创建对象时自动调用,用于初始化对象的状态。
构造方法的作用主要是用于初始化对象的状态,可以在构造方法中对对象的属性进行赋值操作,也可以进行一些其他的初始化操作。通过构造方法,可以确保对象在创建时就具有初始状态,避免了对象在使用过程中出现未初始化的问题。
十一、导包 如import java.io.*;
使用import语句可以导入其他包中的类,以便在当前类中可以直接使用这些类而不需要使用完整的类路径。例如,import java.io.*;语句可以导入java.io包中的所有类,这样就可以在当前类中直接使用java.io包中的类而不需要使用完整的类路径。
十二、static关键字用法,静态变量(类变量)、静态方法的特点和使用方法
在Java中,static关键字用于修饰类的成员变量和方法,使其成为静态变量(类变量)和静态方法。静态变量和静态方法的特点和使用方法如下:
1. 静态变量(类变量):
静态变量属于类,而不是对象,所有实例对象共享同一个静态变量。静态变量可以直接通过类名访问,也可以通过对象名访问。静态变量在类加载时就会被初始化,并且只会被初始化一次。静态变量通常用来表示类级别的属性,如计数器、常量等。
public class MyClass {
public static int count = 0;
}
2. 静态方法:
静态方法属于类,而不是对象,可以直接通过类名调用,不需要实例化对象。静态方法不能访问非静态成员变量和方法,因为非静态成员需要通过对象才能访问。静态方法通常用来提供一些通用的功能,如工具类中的方法。
public class MyUtils {
public static int add(int a, int b) {
return a + b;
}
}
静态变量和静态方法的使用方法:
- -通过类名访问静态变量和静态方法,如MyClass.count、MyUtils.add(1, 2)。
- -静态方法可以直接在类中调用,无需实例化对象。
- -静态变量通常用来表示类级别的属性,静态方法通常用来提供一些通用的功能。
十三、Object类及其equals()和toString()方法
在Java中,Object类是所有类的根类,也就是说所有类都是Object类的子类。Object类中定义了一些通用的方法,其中包括equals()和toString()方法。
1. equals()方法:
equals()方法用于比较两个对象是否相等。在Object类中equals()方法的默认实现是比较两个对象的引用是否相同,即比较内存地址。如果一个类需要比较对象的内容是否相等,通常需要重写equals()方法。
示例:
public class MyClass {
private int value;
// 重写equals方法来比较对象的内容是否相等
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
MyClass other = (MyClass) obj;
return this.value == other.value;
}
}
2. toString()方法:
toString()方法用于返回对象的字符串表示。在Object类中,toString()方法的默认实现是返回对象的类名和哈希码的字符串表示。通常情况下,我们需要重写toString()方法来返回对象的有意义的字符串表示,方便调试和输出。
示例:
public class MyClass {
private int value;
// 重写toString方法来返回对象的有意义的字符串表示
@Override
public String toString() {
return "MyClass{" +
"value=" + value +
'}';
}
}
通过重写`equals()`和`toString()`方法,我们可以根据需求来定义对象的相等性比较和字符串表示形式。这样可以提高代码的可读性和可维护性。
十四.多态,Java中多态的实现方法。
多态是面向对象编程中的一个重要概念,它允许不同的子类对象以统一的方式对待。在Java中,多态可以通过继承和方法重写来实现。
多态的实现方法如下:
1. 继承:
多态的基础是继承,子类可以继承父类的属性和方法。父类引用可以指向子类对象,从而实现多态。这样在编程时可以使用父类类型的引用来引用子类对象,从而实现统一的方式对待不同的子类对象。
示例:
class Animal {
public void makeSound() {
System.out.println("Animal is making a sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog is barking");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Cat is meowing");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
dog.makeSound(); // Output: Dog is barking
cat.makeSound(); // Output: Cat is meowing
}
}
2. 方法重写:
子类可以重写父类的方法,当父类引用指向子类对象时,调用的方法会根据实际对象的类型而执行对应的重写方法。这种动态绑定在运行时确定调用哪个方法,实现了多态的效果。示例:
class Animal {
public void makeSound() {
System.out.println("Animal is making a sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog is barking");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Cat is meowing");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.makeSound(); // Output: Dog is barking
animal = new Cat();
animal.makeSound(); // Output: Cat is meowing
}
}
通过继承和方法重写,Java实现了多态的特性,使得代码更加灵活和可扩展。
十五、方法重载
方法重载是指在同一个类中,可以定义多个同名方法,但是这些方法的参数列表必须不同(参数的类型、个数或顺序不同),这样在调用这些方法时,编译器会根据传入的参数类型和个数来选择调用哪个方法。
方法重载的好处是可以提高代码的可读性和灵活性,可以根据不同的参数类型和个数来执行不同的操作,而不需要为每种情况都定义一个新的方法。
下面是一个简单的例子,展示了方法重载的用法:
public class OverloadExample {
public void printMessage(String message) {
System.out.println(message);
}
public void printMessage(int number) {
System.out.println("Number: " + number);
}
public void printMessage(String message, int number) {
System.out.println(message + " " + number);
}
public static void main(String[] args) {
OverloadExample example = new OverloadExample();
example.printMessage("Hello");
example.printMessage(10);
example.printMessage("World", 20);
}
}
在上面的例子中,OverloadExample类中定义了三个同名方法printMessage,分别接受不同的参数类型。在main方法中,通过调用这些方法来演示方法重载的效果。
十六、 Java中继承特点,子类的继承
在Java中,继承是面向对象编程中的一个重要概念,它允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以继承父类的非私有属性和方法,并且可以重写父类的方法以实现自己的逻辑。
以下是Java中继承的一些特点:
1. 子类继承父类的属性和方法:子类可以访问父类的非私有属性和方法,从而可以重用父类的代码。
2. 子类可以拥有自己的属性和方法:子类可以定义自己的属性和方法,从而扩展父类的功能。
3. 子类可以重写父类的方法:子类可以重写父类的方法,以实现自己的逻辑。这样在调用该方法时,会根据对象的实际类型来确定调用哪个版本的方法。
4. 子类可以继承多个父类的接口:Java中支持多重继承接口,一个类可以实现多个接口。
5. Java中只支持单继承:一个子类只能有一个直接父类。但是可以通过多层继承来间接继承多个父类的属性和方法。
下面是一个简单的例子,展示了子类继承父类的特点:
// 父类
class Animal {
public void eat() {
System.out.println("Animal is eating");
}
}
// 子类
class Dog extends Animal {
public void bark() {
System.out.println("Dog is barking");
}
}
public class InheritanceExample {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // 调用父类的方法
dog.bark(); // 调用子类的方法
}
}
在上面的例子中,Dog类继承了Animal类,因此Dog类可以访问Animal类的eat方法。同时,Dog类还定义了自己的bark方法。在main方法中,创建了一个Dog对象,并调用了eat和bark方法,展示了子类继承父类的特点。
会重写方法、子类重写父类方法时访问控权限不能比父类访问控制访问权限低
方法重写
方法重写是指子类可以重写父类中具有相同名称和参数列表的方法。在子类中重新定义一个与父类中已有的方法具有相同名称和参数列表的方法,这样当子类对象调用该方法时,会执行子类中的方法而不是父类中的方法。
在方法重写时,子类重写的方法不能比父类的方法访问控制权限更低,即子类重写的方法的访问修饰符不能比父类中被重写的方法的访问修饰符更低。例如,如果父类中的方法是public访问权限,那么子类中重写该方法时也必须使用`public`访问权限。
对象之间的转型
在Java中,对象之间的转型分为向上转型和向下转型:
向上转型:是指将子类对象转换为父类对象的过程。这样做可以使子类对象被当做父类对象来使用,但是只能访问父类中定义的属性和方法。向上转型是自动进行的,不需要显式转换。
ParentClass parent = new ChildClass();
向下转型:是指将父类对象转换为子类对象的过程。这样做可以使父类对象恢复为子类对象,从而可以访问子类中定义的属性和方法。向下转型需要显式进行,并且需要使用`instanceof`关键字来判断转换是否安全。
if (parent instanceof ChildClass) {
ChildClass child = (ChildClass) parent;
}
instanceof关键字用法
对象之间的转型 向上转型 instanceof 关键字用法
instanceof`是Java中的一个关键字,用于判断一个对象是否是某个类的实例。其语法为`对象 instanceof 类名,如果对象是指定类或其子类的实例,则返回true;否则返回false。
在向下转型时,可以使用instanceof关键字来判断父类对象是否是子类的实例,以确保转换的安全性。如果不进行判断直接进行向下转型,可能会导致ClassCastException异常。
十七、super关键字、final关键字的用法(final可以修饰类、方法和变量)
super()、super.成员变量、super.成员方法()
super关键字
在Java中,super关键字用于引用父类的成员变量和方法。主要有以下几种用法:
1. super():在子类的构造方法中,可以使用super()调用父类的构造方法。如果子类的构造方法没有显式调用super(),则会默认调用父类的无参构造方法。
2. super成员变量:可以使用super成员变量来访问父类中的成员变量,即使子类中存在同名的成员变量。
3. super.成员方法():可以使用super.成员方法()来调用父类中的方法,即使子类中存在同名的方法。
通过使用super关键字,子类可以访问和调用父类的属性和方法,实现代码的复用和扩展。
final关键字
final关键字在Java中可以修饰类、方法和变量,其主要作用如下:
1. 修饰类:使用final修饰的类不能被继承,即该类为最终类,不能有子类。
final class FinalClass {
// 类的内容
}
2. 修饰方法:使用final修饰的方法不能被子类重写,即该方法为最终方法,子类不能修改该方法的实现。
class ParentClass {
public final void finalMethod() {
// 方法的内容
}
}
3. 修饰变量:使用final修饰的变量为常量,一旦赋值后不能再修改,即该变量的值为只读。
final int constantVariable = 10;
通过使用final关键字,可以保证类、方法或变量的不可改变性,增加代码的安全性和稳定性。
十八、抽象类和抽象方法、抽象类的实现(由其子类实现)
当final和abstract共同修饰方法时,将发生编译错误
抽象类和抽象方法
在Java中,抽象类是用abstract关键字修饰的类,它可以包含抽象方法。抽象方法是没有方法体的方法声明,只有方法的签名,使用abstract关键字修饰。抽象类不能被实例化,只能被用作父类,需要由其子类实现抽象方法。
定义抽象类和抽象方法的语法如下:
abstract class AbstractClass {
// 抽象方法,没有方法体
public abstract void abstractMethod();
}
抽象类的实现
当一个类继承自抽象类时,必须实现抽象类中的所有抽象方法,否则该子类也必须声明为抽象类。子类通过实现父类的抽象方法来提供具体的实现,从而使抽象类变得具体化。
abstract class AbstractClass {
public abstract void abstractMethod();
}
class ConcreteClass extends AbstractClass {
@Override
public void abstractMethod() {
// 具体的实现
}
}
final和abstract共同修饰方法
当final和abstract同时修饰一个方法时,会导致编译错误。因为final修饰的方法表示该方法不能被子类重写,而abstract修饰的方法表示该方法必须被子类实现,这两个修饰符的含义是相互冲突的,因此不能同时使用。
abstract class AbstractClass {
// 编译错误:final方法不能被重写
public final abstract void finalAbstractMethod();
}
因此,在定义方法时,需要根据需求选择合适的修饰符,避免出现冲突。通常情况下,抽象方法应该是abstract修饰的,而不应该与final修饰符一起使用。
十九、接口定义、接口实现、接口中的常量及默认方法特点、抽象方法、接口的继承
Java中的多继承通过接口实现
接口定义
在Java中,接口是一种抽象的数据类型,用interface关键字定义。接口可以包含抽象方法、常量和默认方法,但不能包含成员变量和普通方法的实现。
定义接口的语法如下:
interface MyInterface {
// 抽象方法
void abstractMethod();
// 常量
int CONSTANT = 10;
// 默认方法
default void defaultMethod() {
// 默认方法的实现
}
}
接口实现
一个类可以实现一个或多个接口,通过implements关键字实现接口中定义的抽象方法。实现接口的类必须提供接口中所有抽象方法的具体实现。
class MyClass implements MyInterface {
@Override
public void abstractMethod() {
// 实现抽象方法
}
}
接口中的常量及默认方法特点
1. 常量:接口中的常量默认为public static final,可以直接通过接口名访问。
int CONSTANT = 10;
2. 默认方法:接口中的默认方法使用default关键字修饰,可以在接口中提供默认的方法实现。实现类可以选择是否重写默认方法。
default void defaultMethod() {
// 默认方法的实现
}
接口的继承
接口可以继承其他接口,使用extends关键字。一个接口可以继承多个接口,从而扩展接口的功能。
interface MySubInterface extends MyInterface {
// 可以定义新的抽象方法
void newAbstractMethod();
}
实现类需要实现接口继承链中所有接口的抽象方法。
总结
通过接口的特性,可以实现代码的灵活性和扩展性,实现类可以根据需要选择性地实现接口中的方法,同时接口的继承也可以帮助组织和管理接口之间的关系。
二十、接口与抽象类的不同点
Java中的接口和抽象类都是用于实现多态和封装的机制,但它们之间有一些重要的区别。
1. 定义方式
接口:使用interface关键字定义接口,接口中只能包含抽象方法、常量和默认方法,不能包含成员变量和普通方法的实现。
抽象类:使用abstract关键字定义抽象类,抽象类可以包含抽象方法、普通方法、成员变量以及构造方法等,可以有部分方法的具体实现。
2. 多继承
接口:一个类可以实现多个接口,通过接口可以实现多继承的效果,一个类可以同时具有多个接口的特性。
抽象类:Java不支持多重继承,一个类只能继承一个抽象类,但可以实现多个接口。
3. 实现方式
接口:实现接口的类必须提供接口中所有抽象方法的具体实现,可以通过implements关键字实现接口。
抽象类:抽象类可以包含抽象方法和普通方法,子类必须实现抽象方法,可以通过`extends`关键字继承抽象类。
4. 默认方法
接口:接口中可以定义默认方法,使用default关键字修饰,默认方法可以在接口中提供默认的方法实现,实现类可以选择是否重写默认方法。
抽象类:抽象类中不能包含默认方法,抽象类中的方法必须由子类实现。
5. 构造方法
接口:接口中不能包含构造方法,因为接口不能被实例化。
抽象类:抽象类可以包含构造方法,用于初始化抽象类的成员变量。
总结
接口更加灵活,可以实现多继承和定义行为规范,适用于定义API和实现多种功能。
抽象类更加具体,可以包含成员变量和构造方法,适用于具有共同特征的类的继承关系。
二十一、List、Set、Map接口的特点、父接口
ArrayList与LinkedList的区别、List与Set的区别
List、Set、Map接口的特点、父接口:
1. List接口:List接口继承自Collection接口,它表示一个有序的集合,允许存储重复元素。List接口提供了按索引访问元素、插入元素、删除元素等操作。
2. Set接口:Set接口也继承自Collection接口,它表示一个不允许重复元素的集合。Set接口中的元素是无序的,不可重复的。
3. Map接口:Map接口是键值对的集合,它不继承自Collection接口。Map中的键是唯一的,值可以重复。Map接口提供了根据键获取值、插入键值对、删除键值对等操作。
ArrayList与LinkedList的区别:
1. ArrayList是基于数组实现的List集合,支持随机访问元素,插入和删除元素的效率较高。但在插入和删除元素时可能需要移动其他元素,导致性能下降。
2. LinkedList是基于双向链表实现的List集合,插入和删除元素的效率较高,因为只需要改变相邻节点的指针。但访问元素的效率较低,需要遍历链表。
List与Set的区别:
1. List是有序的集合,允许存储重复元素,可以通过索引访问元素。Set是无序的集合,不允许重复元素。
2. List接口继承自Collection接口,提供了按索引访问元素的功能。Set接口也继承自Collection接口,但不提供按索引访问元素的功能。
二十二、InputSteam与OutputStream是什么类,功能是什么?
FileInputStream
InputStream和OutputStream是Java IO中的抽象类,用于处理字节流的输入和输出操作。
InputStream类是字节输入流的抽象类,它定义了读取字节流的方法,可以从输入源(如文件、网络连接、内存等)读取字节数据。
OutputStream类是字节输出流的抽象类,它定义了写入字节流的方法,可以将字节数据写入输出目标(如文件、网络连接、内存等)。
FileInputStream是InputStream的子类,用于从文件中读取字节数据。它继承了InputStream类的读取方法,可以打开一个文件输入流,从文件中读取数据。FileInputStream通常用于读取文件中的内容并进行处理。
二十三、异常分类,自定义异常,检查性异常、异常处理
异常分类:
1. 检查性异常(Checked Exception):编译器要求程序必须处理的异常,即在代码中必须显式地处理或抛出这类异常,否则会编译报错。例如IOException、SQLException等。
2. 运行时异常(Unchecked Exception):编译器不要求程序必须处理的异常,程序可以选择处理或不处理这类异常。这些异常通常是由程序错误导致的,如空指针异常(NullPointerException)、数组越界异常(ArrayIndexOutOfBoundsException)等。
3. 错误(Error):严重的问题,一般是由于系统故障或资源耗尽等情况引起的,程序无法处理。例如OutOfMemoryError、StackOverflowError等。
自定义异常:
在Java中,可以通过继承Exception类或RuntimeException类来自定义异常。自定义异常通常用于特定业务逻辑或错误情况的处理,可以根据需要添加额外的信息或处理逻辑。
异常处理:
在Java中,可以使用try-catch语句块来捕获和处理异常。try块中包含可能会抛出异常的代码,catch块用于捕获并处理异常。可以使用多个catch块来处理不同类型的异常。另外,还可以使用finally块来执行无论是否发生异常都需要执行的代码,例如资源释放等操作。
示例代码:
try {
// 可能会抛出异常的代码
// 例如:int result = 10 / 0; // 会抛出ArithmeticException
} catch (ArithmeticException e) {
// 捕获ArithmeticException异常
System.out.println("除数不能为0");
} catch (Exception e) {
// 捕获其他异常
System.out.println("发生异常:" + e.getMessage());
} finally {
// 无论是否发生异常都会执行的代码
System.out.println("执行finally块");
}
二十四、内部类概念及特点 什么是成员内部类
内部类是指定义在另一个类内部的类。在Java中,内部类可以分为四种类型:成员内部类、静态内部类、局部内部类和匿名内部类。其中,成员内部类是定义在外部类的成员位置,可以访问外部类的成员变量和方法。
成员内部类的特点包括:
1. 成员内部类可以直接访问外部类的成员变量和方法,包括私有成员。
2. 成员内部类可以定义在外部类的任意位置,与外部类的成员变量和方法同级。
3. 成员内部类可以被外部类的方法实例化并调用。
4. 成员内部类可以拥有自己的成员变量和方法,与外部类的成员变量和方法相互独立。
示例代码如下:
public class OuterClass {
private int outerVar;
public void outerMethod() {
System.out.println("Outer method");
}
public class MemberInnerClass {
public void innerMethod() {
outerVar = 10; // 访问外部类的成员变量
outerMethod(); // 调用外部类的方法
System.out.println("Inner method");
}
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
MemberInnerClass inner = outer.new MemberInnerClass();
inner.innerMethod();
}
}
在上面的示例中,OuterClass是外部类,MemberInnerClass是成员内部类。在main方法中,实例化外部类对象outer,然后通过outer实例化内部类对象inner,并调用内部类的方法innerMethod。内部类可以直接访问外部类的成员变量和方法。
二十五、线程声明周期中五种状态、Thread.sleep(int m)其中m是毫秒、start()
在Java中,线程的声明周期中有五种状态,分别是:
1. 新建状态(New):当线程对象被创建时,线程处于新建状态。
2. 就绪状态(Runnable):当线程调用start()方法后,线程处于就绪状态,表示线程已经被创建并可以开始执行,但还未分配到CPU时间片。
3. 运行状态(Running):当线程获得CPU时间片并开始执行时,线程处于运行状态。
4. 阻塞状态(Blocked):当线程被挂起或者等待某个条件时,线程处于阻塞状态。
5. 终止状态(Terminated):当线程执行完任务或者发生异常导致线程终止时,线程处于终止状态。
Thread.sleep(int m)方法中的参数m是毫秒数,表示线程休眠的时间,即线程暂停执行指定的毫秒数。在调用Thread.sleep()方法时,当前线程会暂停执行并让出CPU时间片,但线程对象仍然保持就绪状态。
start()方法用于启动线程,当调用start()方法时,线程会进入就绪状态并等待系统调度执行。注意,不能直接调用run()方法来启动线程,必须调用start()方法。start()方法会在新线程中执行run()方法的内容。
二十六、包装类 装箱与拆箱
在Java中,基本数据类型(如int、double、boolean等)是不具备面向对象特性的,无法直接参与面向对象的操作。为了使基本数据类型具备面向对象的特性,Java提供了对应的包装类(如Integer、Double、Boolean等),用于将基本数据类型包装成对象。
装箱(Boxing)指的是将基本数据类型转换为对应的包装类对象,例如将int转换为Integer。装箱是通过构造方法或者静态方法实现的。
拆箱(Unboxing)指的是将包装类对象转换为对应的基本数据类型,例如将Integer转换为int。拆箱是通过调用包装类对象的xxxValue()方法实现的,其中xxx表示对应的基本数据类型。
示例代码如下:
// 装箱
int num = 10;
Integer wrappedNum = new Integer(num); // 使用构造方法进行装箱
Integer wrappedNum2 = Integer.valueOf(num); // 使用静态方法进行装箱
// 拆箱
Integer wrappedNum3 = new Integer(20);
int num2 = wrappedNum3.intValue(); // 调用intValue()方法进行拆箱
装箱和拆箱的作用是在基本数据类型和包装类对象之间进行转换,方便在面向对象的环境中处理基本数据类型。在Java 5及之后的版本中,Java引入了自动装箱和拆箱的特性,可以自动地在基本数据类型和包装类对象之间进行转换,使代码更加简洁和易读。
二十七、Socket
在Java中,Socket类是用于实现网络通信的基本类。通过Socket类,可以在客户端和服务器之间建立网络连接,并进行数据的传输。Socket类提供了对TCP协议的支持,可以实现可靠的双向通信。
下面是一个简单的客户端和服务器通信的示例:
服务器端代码
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("Server started. Waiting for client...");
Socket socket = serverSocket.accept();
System.out.println("Client connected.");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = in.readLine();
System.out.println("Client: " + message);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hello from server!");
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8888);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hello from client!");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = in.readLine();
System.out.println("Server: " + message);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例中,服务器端通过ServerSocket监听8888端口,并等待客户端连接。客户端通过Socket连接服务器端的8888端口。服务器端和客户端通过输入输出流进行数据的读写操作。
Socket类提供了一系列方法用于连接、读写数据、关闭连接等操作,是实现网络通信的基础类。需要注意的是,在使用Socket类时,需要处理可能抛出的IOException异常。
二十八、DBC相关接口与类 JDBC操作数据库的步骤
编程题
在Java中,与数据库连接相关的接口和类主要是JDBC(Java Database Connectivity)相关的接口和类。JDBC是Java提供的用于操作数据库的标准接口,通过JDBC可以实现与各种数据库的连接、数据的增删改查操作。
JDBC相关接口和类
- DriverManager类:用于管理数据库驱动程序,负责建立数据库连接。
- Connection接口:表示与数据库的连接,通过Connection对象可以创建Statement、PreparedStatement等对象进行SQL操作。
- Statement接口:用于执行静态SQL语句,并返回执行结果。
- PreparedStatement接口:继承自Statement接口,用于执行预编译的SQL语句,可以防止SQL注入攻击。
- ResultSet接口:表示查询结果集,通过ResultSet对象可以获取查询结果的数据。
- SQLException类:表示SQL异常,JDBC操作中可能会抛出SQLException异常。
JDBC操作数据库的步骤
- 加载数据库驱动:使用Class类的forName()方法加载数据库驱动。
- 建立数据库连接:通过DriverManager类的getConnection()方法建立与数据库的连接。
- 创建Statement或PreparedStatement对象:通过Connection对象创建Statement或PreparedStatement对象,用于执行SQL语句。
- 执行SQL语句:调用Statement或PreparedStatement对象的executeQuery()、executeUpdate()等方法执行SQL语句。
- 处理查询结果:如果是查询操作,通过ResultSet对象处理查询结果。
- 关闭连接:在操作完成后,关闭ResultSet、Statement、Connection等资源。
编程题
请编写一个Java程序,实现以下功能:
- 连接到名为"testdb"的MySQL数据库,用户名为"root",密码为"123456"。
- 创建一个名为"users"的表,包含id(整型)、name(字符串)两个字段。
- 向"users"表中插入一条记录,id为1,name为"Alice"。
- 查询"users"表中的所有记录,并输出到控制台。
import java.sql.*;
public class JDBCExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/testdb";
String username = "root";
String password = "123456";
try {
// 1. 加载数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 建立数据库连接
Connection connection = DriverManager.getConnection(url, username, password);
// 3. 创建Statement对象
Statement statement = connection.createStatement();
// 4. 创建表
String createTableSQL = "CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY, name VARCHAR(50))";
statement.executeUpdate(createTableSQL);
// 5. 插入记录
String insertSQL = "INSERT INTO users VALUES (1, 'Alice')";
statement.executeUpdate(insertSQL);
// 6. 查询记录
ResultSet resultSet = statement.executeQuery("SELECT * FROM users");
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("id: " + id + ", name: " + name);
}
// 7. 关闭连接
resultSet.close();
statement.close();
connection.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
}
注意!!!代码中使用了MySQL数据库,需要先下载并导入MySQL的JDBC驱动jar包。在实际开发中,可以使用try-with-resources语句来自动关闭资源,以避免资源泄漏
二十九、JDBC
JDBC(Java Database Connectivity)是Java提供的用于操作数据库的标准接口。通过JDBC,Java程序可以与各种关系型数据库进行连接,并执行SQL操作,包括查询、插入、更新、删除等操作。
JDBC的主要组件
- 驱动管理器(DriverManager):负责加载数据库驱动程序,并建立数据库连接。
- 数据库驱动程序(Database Driver):由数据库厂商提供的用于与特定数据库进行通信的程序。
- 连接(Connection):表示与数据库的连接,通过Connection对象可以创建Statement、PreparedStatement等对象进行SQL操作。
- 语句(Statement):用于执行SQL语句,并返回执行结果。
- 结果集(ResultSet):表示查询结果集,通过ResultSet对象可以获取查询结果的数据。
- 元数据(MetaData):用于获取数据库的元数据信息,如表结构、列信息等。
JDBC的操作步骤
- 加载数据库驱动程序:使用Class类的
forName()
方法加载数据库驱动程序,例如Class.forName("com.mysql.cj.jdbc.Driver")
。 - 建立数据库连接:通过DriverManager类的
getConnection()
方法建立与数据库的连接,需要指定数据库的URL、用户名和密码。 - 创建Statement或PreparedStatement对象:通过Connection对象创建Statement或PreparedStatement对象,用于执行SQL语句。
- 执行SQL语句:调用Statement或PreparedStatement对象的
executeQuery()
、executeUpdate()
等方法执行SQL语句。 - 处理查询结果:如果是查询操作,通过ResultSet对象处理查询结果。
- 关闭连接:在操作完成后,关闭ResultSet、Statement、Connection等资源,释放数据库连接。
JDBC的优点
- 跨平台性:JDBC是Java标准接口,可以在不同操作系统上运行。
- 灵活性:支持多种数据库,可以轻松切换数据库。
- 安全性:通过PreparedStatement可以防止SQL注入攻击。
- 性能:JDBC底层采用连接池技术,可以提高数据库连接的效率。
总结
JDBC是Java程序与数据库交互的重要工具,通过JDBC可以实现对数据库的增删改查等操作。
三十、接口
接口(Interface)是一种抽象数据类型,用于定义一组方法的规范,但不提供方法的具体实现。接口可以被类实现(implement),实现类必须提供接口中定义的所有方法的具体实现。接口在Java中扮演着重要的角色,用于实现多态性、解耦合等设计原则。
接口的特点
-
接口中的方法默认是抽象方法:接口中的方法没有方法体,只有方法的声明,实现类必须提供方法的具体实现。
-
接口中的变量默认是常量:接口中的变量默认是
public static final
修饰的常量,可以省略这些修饰符。 -
接口可以继承其他接口:一个接口可以继承另一个或多个接口,使用
extends
关键字。 -
接口不能包含构造方法:接口中不能有构造方法,因为接口不能被实例化。
-
一个类可以实现多个接口:一个类可以实现多个接口,通过
implements
关键字实现。
接口的定义
接口使用interface
关键字进行定义,示例:
public interface MyInterface {
void method1(); // 抽象方法
void method2();
int CONSTANT = 100; // 常量
}
接口的实现
实现类使用implements
关键字来实现接口中定义的方法,示例:
public class MyClass implements MyInterface {
@Override
public void method1() {
// 具体实现
}
@Override
public void method2() {
// 具体实现
}
}
接口的应用
- 实现多态性:接口可以实现多态性,一个对象可以根据其接口类型进行引用。
- 解耦合:接口可以将实现类与调用方解耦,提高代码的灵活性和可维护性。
- 规范约束:接口可以定义一组规范,实现类必须按照规范提供方法的实现。
总结
接口是Java非常重要的机制,可以帮助我们实现代码的灵活性、可扩展性和可维护性。通过接口,可以定义规范,实现多态性,实现类与调用方解耦等。
三十一、类、对象与集合的应用
Java编程中,类、对象和集合是非常重要的概念,它们在实际应用中有着广泛的应用。让我们分别介绍它们的应用:
类的应用
- 封装数据和行为:类可以封装数据和行为,将相关的数据和方法组合在一起,提高代码的可维护性和安全性。
- 定义数据模型:类可以用来定义数据模型,描述现实世界中的实体,如人、车、动物等。
- 实现继承:通过类的继承,可以实现代码的复用,子类可以继承父类的属性和方法。
- 实现多态:通过类的多态性,可以实现相同的方法在不同子类中有不同的行为。
对象的应用
- 创建实例:对象是类的实例,通过类创建对象实例,可以在程序中操作和使用这些对象。
- 封装数据:对象封装了类的数据,可以通过对象访问和修改类的属性。
- 调用方法:对象可以调用类中定义的方法,实现对对象的操作和行为。
集合的应用
- 存储和操作数据:集合是Java中用来存储和操作数据的容器,提供了丰富的数据结构和算法。
- 遍历和操作元素:集合提供了丰富的方法来遍历和操作集合中的元素,如增删改查等操作。
- 实现数据结构:集合框架提供了多种数据结构,如List、Set、Map等,可以根据不同的需求选择合适的数据结构。
- 提高代码的灵活性:使用集合可以提高代码的灵活性和可扩展性,使代码更易于维护和扩展。
总结
综上,类、对象和集合是Java编程中重要概念,在实际应用中发挥着重要的作用。通过类和对象可以封装数据和行为,实现代码的复用和扩展;通过集合可以存储和操作数据,提高代码的灵活性和可维护性。