什么是Java
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了 C++里难以理解的多继承、 指针等概念, 因此Java语言具有功能强大和简单易用两个特
征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。
JVM、JRE和JDK的关系
JVM
JVM( Java Virtual Machine),即Java虚拟机,运行在操作系统之上,存在于内存中,与内存打交道,与硬件没有直接 交互,是Java语言实现跨平台的核心。
JVM是一种抽象,虚拟出来的计算机,和实际的计算机一样,它具有指令集并使用不同的存储区域,它负责执行指 令,还要管理数据,内存和寄存器,指令集,寄
存器,类文件的格式,栈,垃圾回收堆,存储区等。
Java虚拟机,是JRE的一部分。它是整个java实现跨平台的最核心的部分,负责解释执行字节码文件,是可运行java字 节码文件的虚拟计算机。所有平台的上的JVM
向编译器提供相同的接口,而编译器只需要面向虚拟机,生成虚拟机能 识别的代码,然后由虚拟机来解释执行。 JVM主要负责运行Java编译器编译后的字节码文
件(*.class文件)。这些字 节码只面向JVM,不同平台的JVM都是不同的,但它们都提供了相同的接口。JVM是Java程序跨平台的关键部分,只 要为不同平台实现
了相应的虚拟机,编译后的Java字节码就可以在该平台上运行。把字节码解释成具体平台上的机器 码执行。JVM自己无法执行,必须要联合JRE中的Java基础&核心
类库才能使用。
JRE
JRE( Java Runtime Environment),即Java运行环境,支持Java程序运行的标准环境,包含JVM标准实现及Java核心类 库。 JRE中包含了Java virtual
machine(JVM),runtime class libraries和Java application launcher,这些是运行 Java程序的必要组件。通过它,Java的开发者才得以将自己开发的程序发布
到用户手中,让用户使用。JRE=JVM+Java 基础和核心类库。
JDK
JDK( Java Development Kit),即Java开发工具包,是一个编写Java应用程序的开发环境,是java的核心所在。
JDK是整个Java的核心,包括了JRE(Java运行环境),同时在jdk文件夹bin(通常我们配置jdk的环境变量的根目录) 目录中包含了一些Java开发工具(例如:
jconsole、javac、java、javadoc、native2ascii、jar等)。JDK=JRE+Java 开发工具(编译器、反编译器、调试器等)。
java三大特性
1、封装,是指隐藏对象的属性和实现细节,仅对外提供公共访问方式;
2、继承,从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力;
3、多态,一个方法可以有多种实现版本,即“一种定义, 多种实现”。
什么是封装
隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。
什么是继承
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的 功能,但不能选择性地继承父类。通过使用
继承我们能够非常方便地复用 以前的代码。
什么是多态
多态就是继承和重写。允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的 行为方式(发送消息就是函数调用)。猫狗都集
成animal,实现各自的吃,跑的方法,表现为多态形式。
重载和重写的区别
Override是重写,Overload是重载。重载可以改变返回值类型,它是方法名相同,参数列表不同,与返回值类型无 关。 方法重写:子类中出现和父类中方法声明
一模一样的方法。返回值类型相同(或者是子父类,多态),方法名 和参数列表一模一样。主要发生在子类和父类的同名方法之间。 方法重载:本类中出现方法
名相同,参数列表不同 的方法,和返回值类型无关,可以改变。主要发生同一类的多个同名方法之间。 子类对象调用方法时,先找子类本 身的方法,再找父类中
的方法。
构造器是否可被重写
构造器不能被继承,因此不能被重写,但可以被重载。
String、StringBuffer 和 StringBuilder 的区别是什么
String
(1)实现了序列化Serializable,Comparable以及CharSequence字符序列接口。String是Java字符串对象,底层是 基于char字符数组,使用了final修饰类,表示最终类,不能被继承和修改,线程安全。
(2)每一次对String声明的对象的内容进行修改,得到的都是另外一个新的字符串常量对象,如果字符串常量池中 已经存在该字符串常量对象,则不会再创建。
(3)String重写了Object类中的equals、hashCode方法,重写后equals方法比较了字符串的每一个字符,而重写
hashCode方法则是由字符串的每一个字符计算出字符串的hashCode值。
stringbuilder
(1)底层继承了AbstractStringBuilder,实现了Serializable、CharSequence接口
(2)底层基于char字符数组,可以修改操作对象,非线程安全
(3)StringBuilder初始化时默认字节数组初始化容量大小为16,当容量大于当前字节数组容量时会自动进行1倍扩 容再加2,每次扩容都会开辟新空间,并且进行
新老字符数组的复制。源码底层通过调用System的一个native本地方 法arraycopy实现新老字符数组的复制,该native方法底层会直接操作内存,比一般的for循
环遍历复制数组的效率要 快很多;
(4)如果要操作拼接字符串,并且拼接的字符串很长,又没有给StringBuilder指定合适的初始化容量大小,可能会 导致底层的字符数组进行多次扩容,多次申请
内存空间来完成新老字符数组的复制,性能开销比较大;
stringbuffer
StringBuffer底层实现与StringBuffer最大的区别在于方法使用了synchronized关键字同步,因此是线程安全的, StringBuilder非线程安全。
jdk1.8的字符串常量拼接是怎样的过程?
String s1 = “jingdian”;
String s2 = “jichi”; String s3 = s1 + s2;
先javac编译java源文件得到Class,再经过javap -c ClassName反编译查看汇编指令发现,发现s1+s2等价于
String s4 = new StringBuffer().append(s1).append(s2).toString();
普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法。 抽象类不能直接实例化,普通类可以直接实例化。
抽象类能使用 final 修饰吗?
不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承, 这样彼此就会产生矛盾,所以 final不能修饰抽象类
成员变量与局部变量的区别有那些
从语法形式上看,成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被 public,private,static 等修饰符所修饰,而局部变量不能被访问控制修饰符及 static 所修饰;但是,成员变量和 局部变量都能被 final 所修饰;
从变量在内存中的存储方式来看,成员变量是对象的一部分,而对象存在于堆内存,局部变量存在于栈内存;
从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法 的调用而自动消失。
成员变量如果没有被赋初值,则会自动以类型的默认值而赋值(一种情况例外被 final 修饰的成员变量也必须显 示地赋值);而局部变量则不会自动赋值。
静态变量和实例变量的区别?
静态变量属于类的级别,而实例变量属于对象的级别。
主要区别有两点:
1、存放位置不同:类变量随着类的加载存在于方法区中,实例变量随着对象的建立存在于堆内存中。
2、生命周期不同:类变量的生命周期最长,随着类的加载而加载,随着类的消失而消失,实例变量随着对象的消失 而消失。
静态的使用注意事项:
1、静态方法只能访问静态成员(包括成员变量和成员方法),不能访问非静态成员或方法。非静态方法可以访问静 态也可以访问非静态方法或成员。
2、静态方法中不能出现this,super关键字。因为静态是优先于对象存在的,所以不能出现this,super关键字。 3、主函数是静态的。
final finally finalize区别
final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示 该变量是一个常量不能被重新赋值。
finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中, 表示不管是否出现异常,该代码块都会执行,
一般用来存放一些关闭资源的代码。 finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调 用,当我们
调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后 判断。
父类的静态方法能否被子类重写?
不能。重写只适用于实例方法,不能用于静态方法,而子类当中含有和父类相同签名的静态方法,我们一般称之为隐藏。 子类可以继承父类的静态方法和静态变量。
什么是Java跨平台性
1、java的跨平台,是指java在运行时是凌驾于os之上,是在jvm中运行的,跟os没有直接联系。
2、java跨平台主要是由java的编译方式决定的,因为java是通过jvm先编译再执行,它编译的.class文件是底层的实 现不是针对操作系统的,所以什么操作系统并不影响java代码的执行。
3、要运行Java程序,必须要安装JDK( Java Development kit),不同的系统需要有不同的JDK。因为JDK内部有JVM(虚 拟机),通过虚拟机,可以将我们的原文件转化为机器最终可以识别的机器语言。虚拟机它其实是借助电脑本身的设 备及其他功能来实现的一个模拟机器。
Java有哪些数据类型
Java的基本数据类型有8种,分别是:byte(位)、short(短整数)、int(整数)、long(长整数)、float(单精 度)、double(双精度)、char(字符)和boolean(布尔值)。
switch是否能作用在byte上,是否能作用在long上,是否能作用在String上?
在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。从 Java5 开始,Java 中引入了枚举类型, expr 也可以是 enum 类型,从 Java 7 开始,expr 还可以是字符串(String),但是长整型(long)在目前所有的版 本中都是不可以的。
short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int型,需要强制转换类型才能赋值给 short 型。 而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其中有隐含的强制类型转 换。
private,public,protected以及不写的区别?
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、 变量、方法。
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意: 不能修饰类(外部类)。
public : 对所有类可见。使用对象:类、接口、变量、方法
final有什么用?
用于修饰类、属性和方法; 被final修饰的类不可以被继承; 被final修饰的方法不可以被重写;
被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可 以改变的;
this与super的区别?
1、super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生 类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)
2、this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成 员数据同名,这时需用this来指明成员变量名)
3、super()和this()类似,区别是,super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。 4、super()和this()均需放在构造方法内第一行。
5、尽管可以用this调用一个构造器,但却不能调用两个。
6、this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会 有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
7、this()和super()都指的是对象,所以,均不可以在static环境中使用。包括: static变量,static方法,static语句 块。
8、从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
== 和 equals 的区别是什么
== : 它的作用是判断两个对象的地址是不是相等。即判断两个对象是不是同 一个对象。(基本数据类型。== 比较的是 值,引用数据类型 == 比较的是内存地址)
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况: 情况1:类没有覆盖equals() 方法。则 通过 equals() 比较该类的两个对象时, 等价于通过“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象 的内容相等;若它们的内容相等,则 返回 true (即认为这两个对象相等)。
hashCode()与equals()的关系
如果两个对象相等,则hashcode一定也是相同的 两个对象相等,对两个对象分别调用equals方法都返回true 两个对 象有相同的hashcode值,它们也不一定是相等的。
JDK 中常用的包有哪些
java.lang:这个是系统的基础类; java.io:这里面是所有输入输出有关的类,比如文件操作等;
java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;
java.net:这里面是与网络有关的类; java.util:这个是系统辅助类,特别是集合类; java.sql:这个是数据库操作的类。
什么是字符串常量池?
字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符 串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在, 则实例化一个字符串放到池中,并返回其引用。
instanceof 关键字的作用
instanceof 严格来说是Java中的一个双目运算符,是用来测试一个对象是否为一个类的实例
1 | boolean result = obj instanceof Class |
其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。 注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能 确定类型,则通过编译,具体看运行时定。
什么是泛型
“泛型”,顾名思义, “泛指的类型”。我们提供了泛指的概念,但具体执行的时候却可以有具体的规则
来约束,比如我们用的非常多的ArrayList就是个泛型类,ArrayList作为集合可以存放各种元素,如 Integer, String, 自定义的各种类型等,但在我们使用的时候通过具体的规则来约束,如我们可以约束集合中只存放Integer类型的元素
Java创建对象有几种方式?
java中提供了以下四种创建对象的方式:
- new创建新对象
- 通过反射机制
- 采用clone机制
- 通过序列化机制
深拷贝和浅拷贝的区别是什么?
- 浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指 向原来的对象.换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。
- 深拷贝:被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向 被复制过的新对象.而不再是原有的那些被引用的对象.换言之.深拷贝把要复制的对象所引用的 对象都复制了一遍。
Java 序列化中如果有些字段不想进行序列化?
transient 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient 修 饰的变量值不会被持久化和恢复。transient 只能修饰变量,不能修饰类和方法。