Java基础-知识点1
Java与C、Python
Java :
- 特点:
- 面向对象:Java是一种严格面向对象的语言,支持类、对象、继承、封装和多态等特性。
- 跨平台:通过JVM,Java程序可以在不同的平台运行。
- 内存管理:Java通过垃圾回收器实现自动内存管理。
- 安全性 :Java 具有严格的安全性机制,如类加载器、安全管理器等
- 使用场景:
- Java 主要用于企业级应用开发、大型系统和跨平台应用程序,如网站后端服务、企业软件等。
C:
- 特点:
- 结构化:C 是一种结构化编程语言,主要通过函数组织代码。
- 速度高:C 编译后的代码执行速度快,适合对性能要求较高的应用。
- 系统级编程:C 语言适用于系统级编程,如操作系统、驱动程序等。
- 使用场景:
- C 主要用于系统编程、嵌入式开发、操作系统和硬件驱动程序等领域。
Python:
- 特点:
- 简洁易学:Python 的语法简洁清晰,易于学习和使用,适合初学者入门。
- 高级特性:Python 支持面向对象、函数式编程、动态类型等高级特性。
- 多范式编程语言,支持面向对象、函数式编程、命令式编程等多种编程范式,灵活性较高。
- 使用场景:
- Python 适合用于数据分析、科学计算、Web 开发、自动化脚本等领域,以及初学者学习编程的入门语言。
java 与 C++的异同
Java 和 C++ 是两种流行的编程语言,它们有一些相似之处,也有一些明显的区别:
相似之处:
- 面向对象: Java 和 C++ 都是面向对象的编程语言,支持类、对象、继承、封装和多态等面向对象的特性。
- 编译型语言: Java 和 C++ 都是编译型语言,需要先编译成中间代码或机器码,然后才能执行。
- 标准库和第三方库: Java 和 C++ 都有丰富的标准库和第三方库,可用于各种开发任务。
区别:
- 平台依赖性:
- Java 是一种平台无关的语言,通过 Java 虚拟机(JVM)实现跨平台性,同样的 Java 程序可以在不同的操作系统上运行。
- C++ 编译后的代码通常是与特定平台相关的,需要针对不同平台进行编译。
- 内存管理:
- Java 使用自动内存管理(垃圾回收器),程序员不需要手动管理内存分配和释放。
- C++ 需要程序员手动管理内存,包括分配和释放内存,这可能导致内存泄漏或越界访问等问题。
- 异常处理:
- Java 使用 try-catch-finally 结构进行异常处理,要求程序员必须显式处理可能出现的异常。
- C++ 也支持异常处理,但更加灵活,程序员可以选择是否处理异常。
- 类的继承:
- Java 的类是单继承的,一个类只能继承一个直接父类。
- C++ 支持多重继承,即一个类可以直接继承多个父类。
Java8的新特性
Java 8 引入了许多重要的新特性,其中包括 Lambda 表达式、Stream API、接口的默认方法和静态方法、函数式接口、Optional 类、日期时间 API 等。
Lambda 表达式:
Lambda 表达式是一种简洁而强大的语法,用于创建匿名函数,可以在不创建单独方法的情况下传递代码块。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println(name));
Stream API:
Stream API 提供了一种高效且易于使用的方式来处理集合数据。它支持函数式编程风格的操作,如过滤、映射、排序、聚合等。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
long count = names.stream()
.filter(name -> name.startsWith("A"))
.count();
System.out.println(count); // 输出:1
接口的默认方法和静态方法:
Java 8 允许接口中定义默认方法和静态方法。默认方法可以在接口中提供默认实现,静态方法则可以直接通过接口名调用。
public interface MyInterface {
default void defaultMethod() {
System.out.println("Default method");
}
static void staticMethod() {
System.out.println("Static method");
}
}
class MyClass implements MyInterface {
// 实现类可以直接调用默认方法和静态方法
public void someMethod() {
defaultMethod();
MyInterface.staticMethod();
}
}
基本数据类型
数据类型 | 大小(位) | 范围 | 默认值 |
---|---|---|---|
byte | 8 | -128 - 127 | 0 |
short | 16 | -32768 - 32767 | 0 |
int | 32 | -231 - ( 231 -1) | 0 |
long | 64 | -263 - (263 - 1) | 0L |
float | 32 | 约 ±3.40282347E+38F | 0.0f |
double | 64 | 约 ±1.79769313486231570E+308 | 0.0d |
char | 16 | 0 到 65,535(‘\u0000’ 到 ‘\uffff’) | ‘\u0000’ |
boolean | - | true 或 false | false |
包装类
包装类是 Java 中的一组类,用于将基本数据类型包装成对象。 在 Java 中,基本数据类型(如 int、float、boolean 等)是直接存储在栈内存中的,而对象则存储在堆内存中。为了让基本数据类型也能像对象一样参与面向对象的操作,Java 提供了对应的包装类。
以下是 Java 中常用的包装类及其对应的基本数据类型:
基本数据类型 | 包装类 | 示例 |
---|---|---|
byte | Byte | Byte b = 10; |
short | Short | Short s = 100; |
int | Integer | Integer i = 1000; |
long | Long | Long l = 100000L; |
float | Float | Float f = 3.14f; |
double | Double | Double d = 3.14159; |
char | Character | Character c = ‘a’; |
boolean | Boolean | Boolean bool = true; |
这些包装类提供了丰富的方法来操作对应的基本数据类型,例如转换成字符串、比较大小、获取最大最小值等。同时,它们还支持自动装箱(Autoboxing)和自动拆箱(Unboxing),使得基本数据类型和其对应的包装类之间可以自动转换,方便了编程过程。
自动装箱与自动拆箱
自动装箱(Autoboxing)和自动拆箱(Unboxing)是 Java 中的两种特性,用于方便地在基本数据类型和对应的包装类之间进行转换,而不需要手动进行转换操作。
自动装箱
自动装箱指的是将基本数据类型自动转换为对应的包装类对象的过程。 当将基本数据类型赋值给对应的包装类对象时,Java 编译器会自动执行装箱操作,将基本数据类型包装成对象。
示例:
int num = 10;
Integer integer = num; // 自动装箱
在这个示例中,将整数 10 赋值给 Integer 类型的对象 integer,编译器会自动将 int 类型的值装箱成 Integer 对象。
自动拆箱
自动拆箱指的是将包装类对象自动转换为对应的基本数据类型的过程。 当将包装类对象赋值给基本数据类型时,Java 编译器会自动执行拆箱操作,将包装类对象中的值提取出来赋给基本数据类型变量。
Integer integer = 100;
int num = integer; // 自动拆箱
在这个示例中,将 Integer 类型的对象 integer 赋值给 int 类型的变量 num,编译器会自动将 Integer 对象拆箱,提取其中的值赋给 int 变量。
基本数据类型和类的区别
基本数据类型(Primitive Data Types)和类(Class)是 Java 中的两种不同的概念,它们有一些重要的区别:
- 存储位置:
- 基本数据类型: 基本数据类型的值存储在栈内存中,它们是直接存储在内存中的简单数据,不需要通过 new 关键字创建对象。
- 类: 类是对象的模板,它的实例存储在堆内存中。通过 new 关键字创建的对象是在堆内存中分配空间,并返回对象的引用。
- 值传递与引用传递:
- 基本数据类型: 基本数据类型的传递是按值传递的,即传递的是值的副本,不影响原始值。
- 类 : 类的传递是按引用传递的,传递的是对象的引用(地址),对对象的修改会影响原始对象。
- 默认值:
- 基本数据类型:有具体的默认值。
- 类:类的默认值是null,即对象引用没有指向任何对象时的值。
- 操作方法:
- 基本数据类型: 基本数据类型没有方法和属性,只能进行基本的算术运算和比较操作。
- 类:类可以包含方法和属性,可以进行更复杂的操作,如调用方法、访问属性等。
缓存池
Java 中的缓存池是指一种用于存储和重复利用对象,降低磁盘访问的机制,旨在提高程序性能和资源利用率。常见的缓存池包括字符串常量池、Integer缓存、对象池等。
字符串缓存池
字符串缓存池是 Java 中用于存储字符串常量的区域,它位于方法区(JVM 内存区域的一部分),用于存储字符串常量和通过常量表达式生成的字符串。 当我们创建一个字符串常量时,如果该字符串已经存在于常量池中,则不会重复创建,而是直接引用常量池中的对象,以节省内存。
//示例
String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2); // 输出:true
Integer缓存
Java 中的 Integer 缓存是指在一定范围内(默认为 -128 到 127),Integer 类会对这些整数值进行缓存,使得同一数值的 Integer 对象在这个范围内可以被重用,而不是每次都创建新的对象。
这种缓存机制是为了节省内存和提高性能而设计的。因为在实际编程中,一些整数值(如小整数)被频繁使用,通过缓存可以减少对象的创建和销毁,同时提高程序的执行效率。
//示例
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // 输出 true,使用了缓存对象
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // 输出 false,超过了缓存范围,会新创建对象
对象池
对象池是一种用于存储和重复利用对象的机制,可以减少对象的创建和销毁次数,提高系统的性能和资源利用率。常见的对象池包括连接池(如数据库连接池、线程池)、对象池(如线程安全的对象池)等。
示例(简化的对象池):
public class ObjectPool<T> {
private List<T> pool;
public ObjectPool() {
pool = new ArrayList<>();
}
public void addObject(T obj) {
pool.add(obj);
}
public T getObject() {
if (!pool.isEmpty()) {
return pool.remove(0);
}
// 如果池为空,则创建新对象
return createObject();
}
private T createObject() {
// 创建新对象的逻辑
return null;
}
}
通过合理使用缓存池,可以减少对象的创建和销毁,提高系统的性能和资源利用率,特别是在需要频繁使用相同对象的场景下,缓存池可以发挥重要作用。
instanceof 关键字的作用
instanceof
是 Java 中的一个关键字,用于检查一个对象是否是某个类或其子类的实例。它的作用是在运行时进行类型检查,以确定对象是否属于特定类或其子类,从而进行相应的类型转换或操作。
//示例
class Animal {}
class Dog extends Animal {}
public class InstanceOfExample {
public static void main(String[] args) {
Animal animal = new Dog();
if (animal instanceof Dog) {
System.out.println("animal 是 Dog 类的实例");
} else {
System.out.println("animal 不是 Dog 类的实例");
}
}
}
//在上面的示例中,animal 是 Dog 类的实例,
//因此 animal instanceof Dog 返回 true,
//输出结果为 "animal 是 Dog 类的实例"。
instanceof
关键字在实际编程中常用于进行类型判断,特别是在多态的情况下,可以在运行时动态确定对象的具体类型,以便进行相应的处理,例如类型转换、调用特定方法等。需要注意的是,instanceof
也适用于判断对象是否实现了某个接口或是数组的情况。
重载与重写的区别
重写(Overriding)
重写指的是子类重新定义(覆盖)了父类中具有相同名称和参数列表的方法,通过 @Override 注解来明确标识。重写的方法必须具有相同的方法签名(方法名、参数列表和返回类型)。
重写的要求 :
- 方法名、参数列表相同:
- 子类方法的访问权限 >= 父类
- 子类方法的返回类型 <=父类的返回类型 (必须 是 父类方法的返回类型或其子类型)
- 子类 抛出的异常 <= 父类
- 如果父类是private修饰的方法,子类不能重写。
- 使用 @Override 注解,可以让编译器帮忙检查是否满足上面的两个限制条件。
//示例
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog barks");
}
}
//Dog 类重写了 Animal 类的 sound 方法,
//在调用 sound 方法时会执行 Dog 类中的方法,
//而不是 Animal 类中的方法。
重载(Overloading)
重载指的是在同一个类中可以定义多个方法,它们具有相同的名称但参数列表不同(参数类型不同、参数个数不同甚至是参数顺序不同)。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。
重载可以提高代码的灵活性和可读性,允许在同一个类中使用相同的方法名来实现不同的功能,根据不同的参数列表调用不同的方法。
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
}
抽象类和接口
抽象类和接口是 Java 中两种用于实现多态性和抽象化的机制。
抽象类(Abstract Class)
抽象类是用 abstract 关键字声明的类,可以包含抽象方法(没有具体实现的方法)和普通方法。抽象类不能直接实例化,需要通过子类来实现并提供具体的实现。
抽象类的特点:
- 包含抽象方法: 抽象类可以包含抽象方法,即没有具体实现的方法。抽象方法使用 abstract 关键字声明,没有方法体,只有方法的声明。子类必须实现抽象类中的所有抽象方法。
- 可以包含普通方法: 抽象类不仅可以包含抽象方法,还可以包含普通的方法,即有具体实现的方法。
- 不能直接实例化: 抽象类不能被直接实例化,即不能使用 new 关键字来创建抽象类的对象。但是可以通过子类继承抽象类,并实现抽象方法来创建对象。
-可以包含成员变量: 抽象类可以包含成员变量,这些成员变量可以被子类继承和访问。 - 支持构造方法: 抽象类可以有构造方法,用于初始化对象。子类在实例化时会调用抽象类的构造方法来完成对象的初始化。
- 可以被继承: 其他类可以继承抽象类,并实现其中的抽象方法,从而实现对抽象类的扩展和特化。
- 不能与 final 关键字一起使用: 抽象类不能与 final 关键字一起使用,因为 final 关键字表示类不可继承,而抽象类需要被子类继承并实现抽象方法。
//示例
public abstract class Animal {
public abstract void makeSound(); // 抽象方法
public void eat() {
System.out.println("Animal is eating");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}
接口(Interface)
接口是一种抽象类型,可以包含抽象方法、常量和默认方法(Java 8+)。接口中的方法默认是抽象的,不需要使用 abstract 关键字声明,使用 interface 关键字定义接口。类通过关键字 implements 实现接口,并实现接口中定义的所有抽象方法。
public interface Animal {//定义接口
void makeSound(); // 抽象方法
default void eat() {
System.out.println("Animal is eating");
}
}
public class Dog implements Animal {//实现接口
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}
共同点与区别
特点 | 接口 | 抽象类 |
---|---|---|
抽象性 | 完全抽象,只能包含抽象方法和常量 | 可以包含抽象方法和具体方法 |
构造方法 | 不能包含构造方法 | 可以 包含构造方法 |
成员变量 | 只能包含常量 | 可以包含常量和成员变量 |
继承与实现 | 只能被其他类实现 | 可以被其他类继承和实现 |
多继承 | 支持多继承 | 不支持多继承 |
默认方法 | 支持 默认方法(Java 8+) | 不支持默认方法 |
静态方法 | 支持 静态方法(Java 8+) | 不支持静态方法 |
设计目的 | 定义行为规范,强调行为特征 | 表示类的层次结构,可以包含具体实现 |
实例化 | 不能被实例化 | 不能被实例化 |