Java 基础学习笔记

本文详细介绍了Java的基础知识,包括基本类型的自动转换、访问权限、重写与重载的规则、抽象类和接口的使用,以及super和final的关键字作用。此外,还探讨了静态成员、初始化顺序、异常处理、反射机制和注解的概念。文章进一步讲解了Java 8的新特性,并对比了Java与C++的主要差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本类型自动转换

float f = 1.1 // 编译错误 “possible lossy conversion from double to float”
1.1默认是double类型,这里为向下转型(double -> float),Java 不能隐式执行向下转型,但可以隐式执行向上转型。
float f = 1 // 编译通过
1默认为int类型,向上转型可以隐式执行。
float f = 1.1f // 编译通过
这里声明1.1是float类型,则无需类型转换。
+=, -=, *=, /= 这几个运算符可以执行隐式类型转换,即自动向下转型:

int i = 3; 
i += 1.0;  // 编译通过 (自动转型,1.0默认为double类型)
i = i + 1.0;  // 编译不通过
System.out.println(i);

在这里插入图片描述

访问权限
  • public: 均可。
  • protected: 包内访问权限 + 子类。
  • 缺省:包内访问权限。
  • private: 除了包含该成员的类之外,其他任何类都无法访问这个成员。(类内的main函数可以访问)
重写(Override)
  • 为了确保满足里氏替换原则,重写有以下限制。
  • 子类方法的访问权限必须大于等于父类方法;
  • 子类方法的返回类型必须是父类方法返回类型或为其子类型。
  • 使用 @Override 注解,可以让编译器帮忙检查是否满足上面的两个限制条件。
重载(Overload)
  • 存在于同一个类中,指一个方法与已经存在的方法名称上相同,但是参数类型、个数、顺序至少有一个不同。
  • 返回值不同,其它都相同的不算是重载。
抽象类
  • 抽象类和抽象方法都使用 abstract 关键字进行声明。抽象类一般会包含抽象方法,抽象方法一定位于抽象类中。
  • 抽象类和普通类最大的区别是,抽象类不能被实例化,需要继承抽象类才能实例化其子类。
接口
  • 接口是抽象类的延伸,在 Java 8 之前,它可以看成是一个完全抽象的类,也就是说它不能有任何的方法实现。
  • 从 Java 8 开始,接口也可以拥有默认的方法实现,这是因为不支持默认方法的接口的维护成本太高了。在 Java 8 之前,如果一个接口想要添加新的方法,那么要修改所有实现了该接口的类。
  • 接口的成员(字段 + 方法)默认都是 public 的,并且不允许定义为 private 或者 protected。
  • 接口的字段默认都是 static 和 final 的(无需声明)。
抽象类和接口的对比
  • 从设计层面上看,抽象类提供了一种 IS-A 关系,那么就必须满足里式替换原则,即子类对象必须能够替换掉所有父类对象。而接口更像是一种 LIKE-A 关系,它只是提供一种方法实现契约,并不要求接口和实现接口的类具有 IS-A 关系。
  • 从使用上来看,一个类可以实现多个接口,但是不能继承多个抽象类。
  • 接口的字段只能是 static 和 final 类型的,而抽象类的字段没有这种限制。
  • 接口的成员只能是 public 的,而抽象类的成员可以有多种访问权限。
super
  • 访问父类的构造函数:可以使用 super() 函数访问父类的构造函数,从而委托父类完成一些初始化的工作。
  • 访问父类的成员:如果子类重写了父类的某个方法,可以通过使用 super 关键字来引用父类的方法实现。
final
  • 对于基本类型,final 使数值不变。
  • 对于引用类型,final 使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。
  • final声明的方法不能被子类重写。如果在子类中定义的方法和基类中的一个 private 方法签名相同,此时子类的方法不是重写基类方法,而是在子类中定义了一个新的方法。
  • final声明的类不允许被继承。
static
  • 静态变量:又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它。静态变量在内存中只存在一份。
  • 实例变量:每创建一个实例就会产生一个实例变量,它与该实例同生共死。
  • 非静态内部类依赖于外部类的对象来创建,而静态内部类不需要外部类的对象来创建。静态内部类不能访问外部类的非静态的变量和方法。
  • 静态导包:import static com.xxx.ClassName.* 在使用静态变量和方法时不用再指明 ClassName,从而简化代码,但可读性大大降低。
初始化顺序
  • 父类(静态变量、静态语句块)
  • 子类(静态变量、静态语句块)
  • 父类(实例变量、普通语句块)
  • 父类(构造函数)
  • 子类(实例变量、普通语句块)
  • 子类(构造函数)
异常

Throwable 可以用来表示任何可以作为异常抛出的类,分为两种: Error 和 Exception。其中 Error 用来表示 JVM 无法处理的错误,Exception 分为两种:

  • 受检异常 :需要用 try…catch… 语句捕获并进行处理,并且可以从异常中恢复。
  • 非受检异常 :是程序运行时错误,例如除 0 会引发 Arithmetic Exception,此时程序崩溃并且无法恢复。
    在这里插入图片描述
反射
  • 反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的类信息,并且可以操作类或对象的内部属性。
  • 程序中一般的对象的类型都是在编译期就确定下来的,而 Java 反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。
  • 反射的核心是 JVM 在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
  • 反射最重要的用途就是开发各种通用框架。很多框架(比如 Spring)都是配置化的(比如通过 XML 文件配置 Bean),为了保证框架的通用性,它们可能需要根据配置文件加载不同的对象或类,调用不同的方法,这个时候就必须用到反射,运行时动态加载需要加载的对象。
  • 每个类都有一个 Class 对象,包含了与类有关的信息。当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。
  • 类加载相当于 Class 对象的加载,类在第一次使用时才动态加载到 JVM 中。也可以使用 Class.forName("com.mysql.jdbc.Driver")这种方式来控制类的加载,该方法会返回一个 Class 对象。
  • 反射可以提供运行时的类信息,并且这个类可以在运行时才加载进来,甚至在编译时期该类的 .class 不存在也可以加载进来。
  • Class 和 java.lang.reflect 一起对反射提供了支持。
注解(Annontation)
  • Annontation是Java5开始引入的新特征,中文名称叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。
  • Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。
  • java.lang.annotation提供了四种元注解。 @Documented – 注解是否将包含在JavaDoc中、@Retention – 什么时候使用该注解、@Target – 注解用于什么地方、@Inherited – 是否允许子类继承该注解。
泛型
  • 泛型只能代表引用类型,不能是基本数据类型。基本数据类型有byte/short/int/long等。引用类型与基本数据类型的区别在于虽然二者保存在栈中,但基本数据类型保存的是实际值,而引用类型保存的是一个对象的内存地址。
  • 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
Java 8的新特性
  • Lambda Expressions
  • Pipelines and Streams
  • Date and Time API
  • Default Methods
  • Type Annotations
  • Nashhorn JavaScript Engine
  • Concurrent Accumulators
  • Parallel operations
  • PermGen Error Removed
  • Java 8新特性详细描述
Java 与 C++ 的主要区别
  • Java 是纯粹的面向对象语言,所有的对象都继承自 java.lang.Object,C++ 为了兼容 C 即支持面向对象也支持面向过程。
  • Java 通过虚拟机从而实现跨平台特性,但是 C++ 依赖于特定的平台。
  • Java 没有指针,它的引用可以理解为安全指针,而 C++ 具有和 C 一样的指针。
  • Java 支持自动垃圾回收,而 C++ 需要手动回收。
  • Java 不支持多重继承,只能通过实现多个接口来达到相同目的,而 C++ 支持多重继承。
  • Java 不支持操作符重载,虽然可以对两个 String 对象执行加法运算,但是这是语言内置支持的操作,不属于操作符重载,而 C++ 可以。
  • Java 的 goto 是保留字,但是不可用,C++ 可以使用 goto。
  • Java 不支持条件编译,C++ 通过 #ifdef #ifndef 等预处理命令从而实现条件编译。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值