Java基础
语言特性
1、Java语言的优点?
-
跨平台性:Java是“一次编写,到处运行”的语言,这得益于Java虚拟机(JVM)的设计,可以在任何支持JVM的平台上运行,不受操作系统和硬件的限制。
-
面向对象:Java是一门纯粹的面向对象编程语言,提供了类和对象的概念,便于模块化设计,易于理解和维护。
-
简单性:Java设计时去掉了C++中容易引起错误的指针等概念,简化了内存管理,使得程序更加安全。
-
安全性:Java提供了安全机制,比如类加载器、字节码校验器等,可以防止恶意代码破坏。
-
健壮性:Java的强类型机制、异常处理和垃圾回收等,使得Java程序更加健壮。
-
多线程支持:Java内置了对多线程的支持,简化了并发编程的复杂性。
-
丰富的API:Java拥有非常丰富的标准类库,涵盖了从基本数据处理到网络编程等各方面,大大简化了开发工作。
-
大型社区支持:由于Java长时间的发展和广泛应用,形成了庞大的开发者社区,提供了大量的开源框架、工具和文档。
-
良好的可移植性:Java应用程序在不同的平台上运行时,通常不需要或者只需要很少的修改。
-
自动垃圾回收:Java的垃圾回收器自动管理对象的生命周期,减少了内存泄漏的可能性。
2、Java如何实现跨平台?
-
编写源代码:开发者使用Java编程语言编写源代码,这些源代码通常是以.java文件的形式存在。
-
编译源代码:源代码通过Java编译器(javac)编译成字节码,这些字节码以.class文件的形式存在。字节码是一种中间代码,他不是特定与任何平台的机器代码。
-
Java虚拟机(JVM):字节码是平台无关的,他可以在任何安装了相应版本JVM的平台上运行。JVM是一个可以执行字节码的虚拟机,他针对不同的操作系统和硬件平台由不同的实现。
-
即时编译(JIT):当字节码被JVM加载时,JVM中的即时编译器(Just-In-Time Compiler)会将字节码转换成目标平台的机器码。这样,Java程序就可以在不同的平台上运行,而不需要开发者针对每个平台分别编译。
-
Java类库:Java提供了丰富的标准类库(API),这些类库也是跨平台的。这意味着无论在哪个平台上,开发者都可以使用相同的类库来编写程序。
3、JDK和JRE的区别?
JDK(Java Development Kit)和JRE(Java Runtime Environment)是Java编程语言的两个核心组成部分,它们之间的关系如下:
-
JDK(Java Development Kit):
-
JDK是Java开发工具包,它提供了开发Java应用程序所需的所有工具和库。
-
JDK包括一个完整的JRE,以及用于编译、调试和运行Java程序的工具,如编译器(
javac
)、调试器(jdb
)、打包工具(jar
)等。 -
JDK还包含了Java标准类库的源代码,开发者可以使用这些源代码来学习和理解Java API的工作原理。
-
JDK是面向Java开发者的,如果你需要开发Java应用程序,那么你需要安装JDK。
-
-
JRE(Java Runtime Environment):
-
JRE是Java运行时环境,它是运行Java应用程序的最低要求。
-
JRE包括Java虚拟机(JVM)、Java核心类库和支持文件,但不包括开发工具,如编译器和调试器。
-
JRE是面向Java程序用户的,如果你只需要运行Java程序,那么你只需要安装JRE。
-
简而言之,JDK是给Java开发者使用的,包含了开发、调试和运行Java程序所需的一切工具;而JRE是给Java程序最终用户使用的,只包含了运行Java程序所需的组件。如果你是一个Java开发者,你会需要安装JDK;如果你只是运行Java程序,那么安装JRE就足够了。
4、Java是按值调用还是引用调用?
Java的调用机制是按值调用(call by value)。这意味着在Java方法调用中,传递的是实际参数值的一个副本,而不是参数本身。根据参数类型的不同,这个副本可以是基本数据类型的值,也可以是对象引用的值。
-
基本数据类型:当基本数据类型(如int、float、char等)作为参数传递时,传递的是这些值的副本。在方法内部对这个值的任何操作都不会影响到原始值,因为它们是两个独立的内存位置。
-
对象引用:当对象作为参数传递时,传递的是对象引用的副本。这个引用指向堆内存中的同一个对象。因此,如果在方法内部改变了对象的属性,那么原始对象也会被改变,因为引用指向的是同一个对象。但是,如果在方法内部改变了引用本身,使其指向一个新的对象,那么原始引用不会改变,因为它只是一个副本。
这是Java中按值调用的一种特殊形式,有时被称为“按共享对象调用”(call by sharing)或“按对象引用调用”(call by object reference)。尽管如此,Java仍然被认为是按值调用的语言,因为在方法调用时,传递的是值(无论是基本数据类型的值还是引用的值)的副本,而不是变量本身。
5、什么是按值调用和引用调用(针对上条补充说明)
在编程语言中,“按值调用”(call by value)和"按引用调用"(call by reference)是两种不同的参数传递机制。然而,Java实际上采用的是一种混合机制,通常被称为"按共享对象调用"(call by sharing)。
-
按值调用(Call by Value):
-
在按值调用中,函数接收的是参数值的一个副本。
-
在函数内部对参数的任何操作都不会影响到原始参数,因为它们是两个完全独立的变量。
-
Java中的基本数据类型(如int、float、char等)就是按值调用的。当一个基本数据类型的变量作为参数传递时,传递的是它的值。
-
-
按引用调用(Call by Reference):
-
在按引用调用中,函数接收的是参数的内存地址(即引用),而不是值的副本。
-
在函数内部对参数的任何操作都会影响到原始参数,因为它们共享同一个内存地址。
-
Java中没有真正的按引用调用机制。尽管如此,当对象作为参数传递时,传递的是对象引用的一个副本。这个副本指向堆内存中的同一个对象,因此在函数内部对对象的修改会影响到原始对象。
-
-
按共享对象调用(Call by Sharing):
-
这是Java中对象参数传递的一种描述方式。传递的是对象引用的副本,但这个副本指向同一个对象。
-
如果在函数内部改变了对象的属性,那么原始对象也会被改变,因为它们共享同一个对象。
-
但是,如果在函数内部改变了引用本身,使其指向一个新的对象,那么原始引用不会改变,因为它只是一个副本。
-
总的来说,Java中的参数传递可以被认为是按值调用的,因为总是传递值(无论是基本数据类型的值还是对象引用的值)。但是,对于对象来说,这个值是一个引用,它允许在函数内部修改对象的属性,这种现象有时会导致混淆,让人误以为Java是按引用调用的。
6、Class类的作用是什么?如何获取一个Class类对象?
在Java中,Class
类是Java反射(Reflection)机制的核心。它代表了一个类的属性和方法在运行时的类型信息。Class
对象包含了关于类的结构信息,包括其方法、字段、构造函数、注释等。Class
类的作用主要体现在以下几个方面:
-
反射:通过
Class
对象,可以在运行时动态地创建对象、调用方法、访问和修改字段等,这就是Java的反射机制。 -
类型识别:
Class
对象可以用来识别对象的类型,比较两个对象是否属于同一个类,或者检查一个对象是否是一个类的实例。 -
加载和初始化:
Class
对象在类加载的过程中被创建,它负责加载类的字节码,并初始化类静态变量和静态代码块。 -
泛型处理:在泛型编程中,
Class
对象可以用来保存和操作泛型类型的实际类型信息。
获取Class
类对象有几种方式:
6.1、使用Class.forName()方法
Class<?> clazz = Class.forName("java.lang.String");
这种方式通常用于动态加载类,当不知道类的具体类型时使用。
6.2、使用.getClass()方法
String s = "hello"; Class<?> clazz = s.getClass();
这种方式适用于已经有一个对象实例的情况。
6.3、使用类名.class属性
Class<?> clazz = String.class;
这种方式适用于已知类的类型的情况。
6.4、使用ClassLoader
的loadClass()
方法
ClassLoader classLoader = this.getClass().getClassLoader(); Class<?> clazz = classLoader.loadClass("java.lang.String");
这种方式也是用于动态加载类,但是它不会执行初始化代码(如静态代码块)。
7、什么是注解?什么是元注解?
在Java中,注解(Annotation)是一种用于为代码添加元数据的机制。注解可以用于提供代码的额外信息,这些信息可以被编译器或其他工具读取,并据此执行特定的操作。注解不会改变代码的执行逻辑,但它们可以用于提供代码分析、编译检查、运行时处理等功能。
注解可以应用于类、方法、字段、参数等,它们可以包含键值对作为参数,也可以没有参数。Java自带了一些内置注解,如@Override
、@Deprecated
和@SuppressWarnings
,同时,开发者也可以自定义注解。
元注解(Meta-annotation)是用于注解其他注解的注解。也就是说,元注解是用来定义或描述注解的属性的。Java提供了几个内置的元注解,这些元注解用于指定自定义注解的行为和作用范围。以下是一些Java标准库中的元注解:
7.1、@Target:指定注解可以应用于哪些元素(如方法、字段、类等)
@Target(ElementType.METHOD) public @interface MyAnnotation { }
7.2、@Retention:指定注解的信息保留到什么时候(如源代码、字节码或运行时)
@Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { }
7.3、@Documented:指示注解将被包含在生成的文档中。
@Documented public @interface MyAnnotation { }
7.4、@Inherited:指示注解可以被继承,即子类可以继承父类的注解
@Inherited public @interface MyAnnotation { }
7.5、@Repeatable:Java 8引入的元注解,允许在同一元素上多次使用同一个注解。
@Repeatable(MyAnnotations.class) public @interface MyAnnotation { }
通过使用元注解,开发者可以创建具有特定功能和用途的自定义注解,这些注解可以用于代码分析和工具开发,也可以用于框架中提供额外的功能。
8、什么是泛型?泛型有什么作用?
泛型(Generics)是Java 5引入的一个特性,它允许在编程时使用类型参数,这样可以在不牺牲类型安全的情况下编写可重用的代码。泛型使得集合(如List、Set、Map等)和其他类型的类、接口和方法能够以一种类型无关的方式操作,同时还能在编译时提供类型检查。
泛型的作用:
<