1、面向对象编程有哪些特征?
1、封装(Encapsulation)
封装就是指隐藏对象的属性和实现细节,控制成员属性的访问和修改权限,通过特定公开的方法暴露给外面访问。
比如:
private String name="王二";
public String getName(){
return this.name;
}
name属性被 private 封装起来,外面只能通过对象的 getName 才能访问
2、继承(Inheritance)
继承就是指子类继承父类的成员和方法,使得子类也能具有父类相同的行为。
java 类只能实现单继承。
3、多态(Polymorphism)
多态是指同一个行为具有多个不同的表现形式或形态,如一个类的方法在不同的情况下有不同表现形式。
比如:方法重载,同一个方法名可以有不同参数的表现形式。
2、JDK与JRE的区别是什么?
JDK
JDK 全称:Java Development Kit , 是整个 Java 的核心,包含了 Java 运行环境 (JRE)和一系列 Java 开发工具完整的包。
JRE
JRE全称:Java Runtime Enviroment,是 Java 程序的运行环境,包含 JVM , Java 核心类库等。
JRE 只能用来运行 Java 应用程序,不能用来编译开发,它是 JDK 的子集。
一张图看懂它们的关系:
安装完 JDK 后,就会有 JRE 目录,JRE 属于JDK 的子集。
3、如何编译和运行 java 文件?
1、使用 javac 命令来编译 .Java 文件
javac Test.java
运行之后会生成 Test.class 文件
2、使用 java 命令来运行
java Test
4、Java中的关键字有哪些?
5、Java标识符命名规则是怎样的?
- 标识符只能由字母 (a-z,A-Z),数字(0-9),下划线(_)和美元符号($)组成;
- 标识符不能以数字开头;
- 标识符不能使用 Java 关键字;
- 标识符区分大小写;
6、Java类命名规范是怎样的?
类名首字母大写,后面每个单词首字母大写,符合 UpperCamelCase大驼峰式风格,如:
- Order
- OrderDetail
- OrderMonthSummary
但一般像这种众所周知的缩写例外: DO 、BO、DTO、VO、AO、PO、UID 等。
7、Java方法命名规范是怎样的?
方法名首字母小写,后面每个单词首字母大写,符号小驼峰式,如:
- println
- indexOf
- saveOrderInfo
8、Java变量命名规范是怎样的?
变量命名规范:
变量包括方法参数名、成员变量、局部变量。
变量首字母小写,后面每个单词首字母大写,合lowerCamelCase小驼峰式风格,如:
- amount.
- orderPrice
- orderStocklnfo
9、Java常量命名规范是怎样的?
常量命名规范:
常量名全部大写,单词间用下划线(_)隔开,如:
- MAX_LIMIT
- MAX_LOOP_COUNT
- ALIPAY PAY URL
10、Java常量和变量的区别?
Java常量和变量的主要区别在于:
常量是一个固定的值,赋值后是不能被改变的;
变量是一个不固定的值,赋值后是可以随时被改变的;
11、Java 怎样定义一个常量?
Java使用final关键字来定义一个常量,如:
final int MAX.COUNT = 100;
可以加修饰范围,以及静态关键字。
12、Java 常量有几种类型?
Java常量有三种类型:
1、静态常量
2、成员常量
3、局部常量
13、Java 有哪几种基本数据类型?
Java有4类8种数据类型,它们分别是:
1、整型
byte、short、int、long
2、浮点型
float、double
3、字符型
char
4、布尔型
boolean
14、== 和 equals 比较有什么区别?
==:
如果比较的对象是基本数据类型,则比较的是数值是否一致;
如果比较的是引用数据类型,则比较的是对象的地址是否一致。
equals():
equals() 默认用来比较对象的地址是否一致,不能用于比较基本数据类型,如果对象和自身进行比较,则 equals() 方法与 == 的作用是一样的。
public boolean equals(0bject obj) {
return (this == obj);
}
那为什么常用equals()来比较String字符串的内容相等是为什么呢?
那是因为对于 String、Date、Integer 等类型重写了 equals 方法,使其比较的是存储对象的内容是否相等,而不是堆内存地址。
如String类,已经重写了equals方法:
public boolean equals(Object an0bject){
if (this == an0biect){
return true;
}
if (an0bject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- !=0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
15、Java 支持 xx ≠ null 不等于写法吗?
不支持,正常的不等于写法是: !=
如果你见到这种写法是开发工具里面的特效,只是一种字体显示而已。
16、public、private、protected,默认的区别?
类的成员不写访问修饰时默认为default,默认对于同一个包中的其他类相当于公开(public),对于不是同一个包中的其他类相当于私有(private)。
受保护(protected) 对子类相当于公开,对不是同一包中的没有父子关系的类相当于私有。
Java 中,外部类的修饰符只能是 public 或默认,类的成员((包括内部类)的修饰符可以是以上四种。
17、this 和 super 有什么区别?
this: 代表当前对象本身;
this (…): 调用本类的构造方法;
this. 成员变量: 调用当前对象的成员变量;
this. 成员方法(…): 调用本类的成员方法;
super: 代表当前对象的父类;
super(…): 调用父类的构造方法;
super.成员变量: 调用父类的成员变量;
super.成员方法(…): 调用父类的成员方法;
18、Java 中的运算符有哪些?
java 中的运算符有以下几类:
优先级从高到底排列:
19、s1 = s1 +1 和 s1+=1 的区别?
如果s1原有数据类型小于int类型,如: short s1= 10,则s1=s1+1会发生编译异常。
而s1+=1则不会有任何问题,因为s1+=1有隐式强制类型转换,会自动提升为计算结果的数据类型。
20、short s1 = 1; s1+=1;有错吗?
没错,可以正常编译,如下图所示:
public static void main(String[]args) {
short s1 = 1;
S1 += 1;
}
}
因为s1+= 1;相当于s1= (short)(s1+ 1);
其中有隐式强制类型转换。
21、short s1 = 1;s1=s1+1;有错吗?
有错、如下所示:
public static void main(String[] args){
short s1 = 1;
s1 = s1 +1;
}
s1 = s1 +1;会报错
因为1是 int 类型,因此 s1+1 运算结果也是int类型,需要强制转换类型才能赋值给short型。
public static void main(String[] args){
short s1 = 1;
s1 = (short)(s1 +1);
}
22、float n=1.8有错吗?
有错! ! !
1.8是双精度数,将双精度型(double)赋值给单精度型浮点型( float))属于下转型( down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换:
float n=(float) 1.8
或者写成:
float f= 1.8F
23、i++ 和 ++i 的区别?
i++是先赋值后再加,++i是先加后再赋值。
24、while和do while有啥区别?
while 和 do while 都是循环语句,不同的是,while是先判断条件再执行循环,而do while是先执行循环再判断条件:
public static void main(String[] args){
int i = 0;
while (i < 5){
System.out.println( "i 三”t材i式
}
i = 0;
do {
System.out.println( "i =" + ++i);
}while (i< 5);
}
所以说,在同样条件下,如果初始条件不成立,do while是会多执行一次的。
25、如何跳出Java 中的循环?
可以使用以下关键字:
continue:跳出当前本次循环:
break:跳出整个循环;
return:跳出整个循环及当前方法;
26、如何跳出Java中的多层嵌套循环?
可以在最外面的循环语句前定义一个标号,然后在最里层循环体中使用break标号语句跳出嵌套循环,如:
public static void main(String[] args){
javastack:
for (int i =0; i < 100;i++){
for (int j=0j<100;j++){
System.out.println(“1=" + i + ",j=" +j);
if(j==66){
break javastack;
}
}
}
27、& 和 && 的区别
& 和 && 都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为 true 时,整个运算结果才为 true,否则,只要有一方为 false,则结果为 false。
&& 还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式。
& 还可以用作位运算符,当 & 操作符两边的表达不是 boolean 类型时,&表示按位与操作,我们通常使用OxOf 来与一个整数进行&运算,来获取该整数的最低4个 bit 位,例如,0x31& OxOf的结果为0x01。
28、Java怎么进行数组初始化?
方法—:
//一维数组
int [ ] arr = new int [ 5 ];
//二维数组
int [ ] [ ] arr = new int[ 3 ][ 4] ;
方法二:
/ /一维数组a面试库
int [] arr = { 1,2, 3, 4 , 5};
29、数组有没有 length() 方法? String 呢?
数组没有 length() 方法,但是有 length 属性。
String 有length() 方法。
30、怎么理解值传递和引用传递?
值传递:
传递的是基本类型参数的字面量值的拷贝,方法对参数的修改不会影响之前参数的值。
引用传递:
传递的是该参量所引用的对象在堆中地址值的拷贝,而不是拷贝整个对象本身,方法对参数的修改会直接影响参数之前的值。
严格来说,Java 只有值传递,看传递的对象是基本数据类型,还是引用类型,仅此而已。
31、Java到底是值传递还是引用传递?
Java中方法参数严格来说是按值传递的。
如果参数是基本类型:传递的是基本类型的字面量值的拷贝。
如果参数是引用类型:传递的是该参量所引用的对象在堆中地址值的拷贝。
32、Java 中的注释有哪些写法?
- 单行注释://
- 块注释:/**/
- 文档注释:/****/
33、Java 中的构造方法是什么?
构造方法是构造类的主要方法,Java中的每个类都必须要有构造方法,构造方法名和类名相同,没有返回类型,new 一个对象的时候就会调用指定的构造方法,如:
public class Test{
private int id;
public Test(){
this.id = 100 ;
}
}
如果只有一个默认的构造方法,则可以省略。
34、一个类可以有多少个构造方法?
一个类至少要有一个构造方法,也可以有多个构造方法,即构造方法重载(方法参数数量或者类型不同),如果没有显式地创建构造方法,Java 编译器也会为该类提供一个默认构造方法。
如代码所示:
public class Test{
private int id;
public Test(){
this.id =100;
}
public void Test(double fid){
this.id = (int) fid;
}
public Test(String sid){
this.id = Integer.parseInt(sod);
}
}
这里有2个构造方法,void这个方法含有返回类型void,不是构造方法。
35、static 关键字有什么用?
static 代表“静态”的意思,可以用来修饰内部类、类的成员方法、类的成员变量,以及 static 静态代码块。
36、static 变量和普通变量的区别?
1、所属目标不同
静态变量属于类的变量,普通变量属于对象的变量。
2、存储区域不同
静态变量存储在方法区的静态区,普通变量存储在堆区。
另外:JDK7及以上,静态变量存储在其对应的Class对象中,而Class对象和其他普通对3象一样,都存储在堆中的。
3、加载时间不同
静态变量是随着类的加载而加载,随着类的消失而消失;
普通变量随着对象的加载而加载,随着对象的消失而消失。
4、调用方式不同
静态变量只能通过类名、对象调用,
普通变量只能通过对象调用。
37、static 可以修饰局部变量么?
不能是局部变量,可以是内部类、全局变量、方法、代码块。
38、final 关键字有哪些用法?
**1. 修饰类:表示该类不能被继承。
2. 修饰方法:表示该方法不能被重写。
3. 修饰变量:**表示该变量是一个常量、只能赋值一次、不能被修改。
39、39. final、finally、finalize有什么区别?
final:
是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变量,则表示此方法和此变量不能在被改变,只能使用。
finally:
是 try{} catch{}finally{}最后一部分,表示不论发生任何情况都会执行,finally 部分可以省略,但如果finally部分存在,则一定会执行 finally 里面的代码。
finalize:
是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。
40、Java支持多继承吗?
Java 类与类之间不支持多继承,只能单继承:
Java 接口与接口之间支持多继承:
41、Java 类可以实现多个接口吗?
可以的、一个类可以实现多个接口。
42、重载和重写有什么区别?
重载(Overload) :
- 在一个类中,具有相同的方法名,但是方法的参数不同,返回值类型可以相同也可以不同。
- 被重载的方法必须改变参数列表(参数个数或类型不一样);
- 被重载的方法可以改变返回类型; 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
重写(override):
一般都是表示子类和父类之间的关系,其主要的特征是:方法名相同,参数相同,但是具体的实现不同。
- 参数列表与被重写方法的参数列表必须完全相同。
- 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5及更早版本返回类型要一样,java7及更高版本可以不同)。
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明对public,那么在子类中重写该方法就不能声明为protected。
- 父类的成员方法只能被它的子类重写。
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private 和 final的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非 final方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个类,则不能重写该类的方法。
43、构造器可以被重载和重写吗?
一个类的构造器不能被继承,所以它不能被重写。
一个类里面可以有多个构造器,所以它可以被重载。
44、私有方法能被重载或者重写吗?
可以重载,不能重写。
45、静态方法能被重载或者重写吗?
静态方法可以被重载,一个类可以存在多个同名但不同参数的static方法。
静态方法不可以被重写,如果子类也定义了相同的,会被子类同名的静态变量,静态方法所隐藏。
46、静态方法可以被继承吗?
父类的静态属性、静态方法可以被子类继承,但是如果子类也定义了相同的,那就会被子类同名的静态变量,静态方法所隐藏。
47、Java 异常有哪些分类?
下面是Java异常类的组织结构, 红色区域的异常类表示是程序需要显示捕捉或者抛出的。
Throwable
Throwable是Java异常的顶级类,所有的异常都继承于这个类。
Error,Exception是异常类的两个大分类。
Error
Error是非程序异常,即程序不能捕获的异常,一般是编译或者系统性的错误,如 OutOfMemorry 内存溢出异常等。
Exception
Exception 是程序异常类,由程序内部产生。Exception 又分为运行时异常、非运行时异常。
运行时异常
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用 try-catch 语句捕获它,也没有用 throws 子句声明抛出它,也会编译通过,运行时异常可处理或者不处理。
常见的运行时异常如 NullPointException .ArrayIndexOutOfBoundsException等。
非运行时异常
非运行时异常是程序必须进行处理的异常,捕获或者抛出,如果不处理程序就不能编译通过。如常见的 IOException、ClassNotFoundException 等。
48、Error 和 Exception 有什么区别?
Error 和 Exception 都属于异常总父类 Throwble的子类:
Error表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题。比如内存溢出,不可能指望程序能处理这样的情况。
Exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题,也就是说,它表示如果程序运行正常,从不会发生的情况。
49、Java 中常见的异常有哪些?
异常是Java程序中经常遇到的问题,我想每一个Java程序员都讨厌异常,一个异常就是一个BUG,就要花很多时间来定位异常问题。
1、NullPointerException
空指针异常,操作一个 null 对象的方法或属性时会抛出这个异常。
2、OutOfMemoryError
内存异常异常,这不是程序能控制的,是指要分配的对象的内存超出了当前最大的堆内存,需要调整堆内存大小(-Xmx)以及优化程序。
3、IOException
IO,即: input, output,我们在读写磁盘文件、网络内容的时候经常会生的一种异常,这种异常是受检查异常,需要进行手工捕获。
如文件读写会抛出 IOException:
4、FileNotFoundException
文件找不到异常,如果文件不存在就会抛出这种异常。
如定义输入输出文件流,文件不存在会报错:
FileNotFoundException 其实是 IOException 的子类,同样是受检查异常,需要进行手工捕获。
5、ClassNotFoundException
类找不到异常,Java开发中经常遇到,是不是很绝望?这是在加载类的时候抛出来的,即在类路径下不能加载指定的类。
看一个示例:
它是受检查异常,需要进行手工捕获。
6、ClassCastException
类转换异常,将一个不是该类的实例转换成这个类就会抛出这个异常。
如将一个数字强制转换成字符串就会报这个异常;
这是运行时异常,不需要手工捕获。
7、NoSuchMethodException
没有这个方法异常,一般发生在反射调用方法的时候,如:
它是受检查异常,需要进行手工捕获。
8、IndexOutOfBoundsException
索引越界异常,当操作一个字符串或者数组的时候经常遇到的异常。
如图所示,他是运行时异常,不需要手工捕获。
9、ArithmeticException
算术异常,发生在数字的算术运算时的异常,如-个数字除以О就会报这个错。
double n = 3/0;
这个异常虽然是运行时异常、可以手工捕获抛出自定义的异常,如:
10、SQLException
SQL异常,发生在操作数据库时的异常。如下面的获取连接:
又或者是获取下一条记录的时候:
boolean next() throws SQLException ;
它是受检查异常,需要进行手工捕获。
50、Java 中常见的运行时异常有哪些?
常见的运行时异常( RuntimeException)主要有:
1、NullPointerException:空指针异常
2、IndexOutOfBoundsException:下标越界异常
3、NegativeArraySizeException:负数组长度异常
4、ArithmeticException:算术异常
5、ClassCastException:类型强制转换异常
6、SecurityException:违背安全原则异常
51、运行时异常与受检查异常有什么区别?
运行时异常:
表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。
受检查异常:
跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。
区别:
Java编译器要求方法必须用(try/ catch)声明抛出可能发生的受检查异常,但是并不要求必须声明抛出未被捕获的运行时异常。
如:
空指针异常(NullPointerException)是运行时异常
IO异常 (IOException) 是受检异常:
52、什么时候会发生空指针异常?
当一个变量的值为null时,在Java里面表示一个不存在的空对象,没有实际内容,没有给它分配内存,null也是对象成员变量的默认值。
所以,一个对象如果没有进行初始化操作,这时候,如果你调用这个对象的方法或者变量,就会出现空指针异常。
如下面示例会发生空指针异常:
从类结构图来看,空指针它是属于运行时异常RuntimeException的子类,它不是捕获型的,只有在程序运行时才可能报出来,而且会造成程序中断。
53、你知道有哪些避免空指针的方法?
下面说几个空指针的几个最常见的案例及解决之道。
1、字符串比较,常量放前面
这个时候status可能为null造成空指针异常,应该把常量放前面,就能避免空指针异常。
这个应该在各种开发规范里面都会提到,也是最基础的。
2、初始化默认值
在对象初始化的时候给它一个默认值或者默认构造实现,如:
3、返回空集合
在返回一个集合的话,默认会是null,统一规范返回一个空集合。
举个List例子,如:
这样接收方就不用担心空指针异常了,也不会影响业务。
4、断言
断言是用来检查程序的安全性的,在使用之前进行检查条件,如果不符合条件就报异常,符合就继续。
Java中自带的断言关键字:assert,如:
输出:
不过默认是不启动断言检查的,需要要带上JVM参数: -enableassertions才能生效。
Java中这个用的很少,建议使用Spring 中的,更强大,更方便好用。
Spring中的用法:
5、Optional
Optional 是JDK8新增的新特性,再也不用null来判断了,这个在一个对象里面的多个子对象连续判断的时候非常有用。
这里大概介绍了5种,其实还有更多,如何避免空指针,一是要注意代码编写规范,二是要提高代码素养。
54、throw和throws的区别?
- throw : 是真实抛出一个异常
- throws : 是声明可能会抛出一个异常
55、try-catch-finally中哪个部分可以省略?
try-catch-finally其中catch 和finally都可以被省略,但是不能同时省略,也就是说有try的时候,必须后面跟一个catch或者finally。
最近有粉丝反馈说,只需要try,catch 和finally全部可以省略,throws 异常即可,真的是这样吗?
显然是不行的!
56、Java可以一次catch多个异常吗?
Java 7开始可以一次 catch 多个异常,比如:
57、int和Integer有什么区别?
1、Integer是int的包装类,int则是java的一种基本数据类型;
2、Integer变量必须实例化后才能使用,而int 变量不需要;
3、Integer 实际是对象的引用,当new 一个lnteger 时,实际上是生成一个指针指向此对象而int则是直接存储数据值;
4、Integer的默认值是null,int的默认值是0
58、什么是包装类型?有什么用?
什么是包装类型
Java设计当初就提供了8种基本数据类型及对应的8种包装数据类型。我们知道Java是一种面向对象编程的高级语言,所以包装类型正是为了解决基本数据类型无法面向对象编程所提供的。
下面是基本数据类型与对应的包装类型。
下面是包装类型的继承结构图。
从以上图表可以对基本类型和包装类型有一个全面的了解。
包装类应用场景
1、集合类泛型只能是包装类;
//编译报错
List<int> list1 = new ArrayList<>();
//正常
List<Integer> list2 = new ArrayList<>();
2、成员变量不能有默认值;
private int status;
基本数据类型的成员变量都有默认值,如以上代码status 默认值为0,如果定义中0代表失败,那入就会有问题,这样只能使用包装类Integer,它的默认值为null,所以就不会有默认值影响。
3、方法参数允许定义空值;
private static void test1(int status){
System.out.println(status);
}
看以上代码,方法参数定义的是基本数据类型int,所以必须得传—个数字过来,不能传 null,很多场合我们希望是能传递null的,所以这种场合用包装类比较合适。
还有更多应用场景就不―一例举了,欢迎留言共同探讨包装类的更多的应用场景。
59、什么是自动装箱、拆箱?
自动装箱、拆箱
Java 5增加了自动装箱、拆箱机制,提供基本数据类型和包装类型的相互转换操作。
自动装箱
自动装箱即自动将基本数据类型转换成包装类型在Java 5之前,要将基本数据类型转换成包装类型只能这样做,看下面的代码。
Integer i1 = new Integer(8);
Integer i2=Integer.valueOf(8);
//自动装箱
Integer i3= 8;
以上3种都可以进行转换,但在Java 5之前第3种方法是编译失败的,第3种方法也正是现在的自动装箱功能。另外,第一种构造器方法也不推荐使用了,已经标为废弃了。
其实自动装箱的原理就是调用包装类的valueOf方法,如第2个方法中的Integer.valueOf方法。
自动拆箱
自动拆箱即自动将包装类型转换成基本数据类型,与自动装箱相反,有装就有拆,很好理解。
int i4 = i3;
int i5 = i3.intValue();
继续上面的例子,把i3赋值给i4就是实现的自动拆箱功能,自动拆箱的原理就是调用包装类的xxValue方法,如i5中的 Integer的 intValue方法。
自动装箱、拆箱不只是体现在以上的例子,在方法接收参数、对象设置参数时都能自动装箱拆箱。
需要注意的是,关于 Integer, -128~127会有缓存,对比这个范围的值的对象是一个坑,这个在阿里巴巴规范中也有提及。
60、你怎么理解Java中的强制类型转换?
强制类型转换
强制类型转换我们再清楚不过了,即强制显示的把一个数据类型转换为另外—种数据类型。
如:
short s = 199;
int i = s;
double d = 10.24;
long ll = (long) d;
以上的转换结果都在我们的预期之内,属于正常的较换和丢失精度的情况,下面的例子就—样属于数据溢出的情况。
int ii = 300;
byte b = (byte)ii;
300已经超出了byte类型表示的范围,所以会转换成一个毫无意义的数字。
61、你怎么理解Java中的自动类型转换?
自动类型转换
自动类型转换是指:数字表示范围小的数据类型可以自动转换成范围大的数据类型。
如:
long l = 100;
int i = 200;
long ll = i;
具体自动转换如下图所示:
实线表示自动转换时不会造成数据丢失,虚线则可能会出现数据丢失问题。
自动转换也要小心数据溢出问题,看下面的例子。
int count = 100000000;
int price = 1999;
long totalPrice = count * price;
编译没任何问题,但结果却输出的是负数,这是因为两个int相乘得到的结果是int,相乘的结果超出了int的代表范围。这种情况,一般把第一个数据转换成范围大的数据类型再和其他的数据进行运算。
int count = 100000000;
int price = 1999;
long totalPrice = (long) count * price;
另外,向下转换时可以直接将int常量字面量赋值给byte、short、char等数据类型,而不需要强制转换,只要该常量值不超过该类型的表示范围都能自动转换。
62、你怎么理解Java中的类型提升?
类型提升
所谓类型提升就是指在多种不同数据类型的表达式中,类型会自动向范围表示大的值的数据类型提升。
把上面的溢出的例子再改下。
long count = 100000000;
int price = 1999;
long totalPrice = price * count;
price为int型,count 为 long 型,运算结果为long型,运算结果正常,没有出现溢出的情况。
63、怎么理解Java中的多态机制?
方法的重写Overriding和重载Overloading是Java多态性的不同表现。
重写Overriding是父类与子类之间多态性的一种表现,重载 Overloading是一个类中多态性的一种表现。
64、Java如何获取用户的输入?
可以通过Scanner类来获取用户的输入,即︰java.util.Scanner。
基本语法:
Scanner s = new Scanner(System.in);
然后通过next()或者nextLine()方法获取输入字符串。
65、switch是否能用在long 上?
长整型 (long)在目前所有的版本中都是不支持的。
66、switch是否能用在String 上?
从 Java 7 开始,是可以用在字符串(String)上的
67、switch case支持哪几种数据类型?
Java 中 switch case语句用来判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。
语法格式如下:
这里的 expression 都支持哪些类型呢?
- 基本数据类型: byte, short, char, int
- 包装数据类型: Byte, Short, Character,lnteger
- 枚举类型:Enum
- 字符串类型:String (Jdk 7+开始支持)
基本数据类型和字符串很简单不用说,下面举一个使用包装类型和枚举的,其实也不难,注意只能用在switch块里面。
以下为官网的介绍文档。
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
使用switch case语句也有以下几点需要注意。
1.case里面必须跟break,不然程序会一个个case执行下去,直到最后一个break的 case或者default 出现。
2.case条件里面只能是常量或者字面常量。
3.default语句可有可无,最多只能有一个。
68、String属于基础的数据类型吗?
String 不属于基础数据类型。
69、String 类的常用方法都有那些?
-
indexOf():返回指定字符的索引。
-
charAt():返回指定索引处的字符。
-
replace():字符串替换。
-
trim():去除字符串两端空白。
-
split()∶分割字符串,返回一个分割后的字符串数组。
-
getBytes():返回字符串的 byte类型数组。
-
length():返回字符串长度。程
-
toLowerCase():将字符串转成小写字母。
-
toUpperCase():将字符串转成大写字符。
-
substring()∶截取字符串。
-
equals():字符串比较。
70、String字符串如何进行反转?
使用 StringBuilder 或者 StringBuffer 的reverse() 方法。
71、String字符串如何实现编码转换?
如代码所示,把 GBK 字符串转换成 UTF-8:
72、String 与 byte[]之间如何转换?
String > byte[] 通过String 类的getBytes方法;
byte[]> String通过new String(byte[])构造器。
73、String.trim()方法有什么用?
去掉自出穿首尾的空白字符。
74、字符串分割有哪些方式?
1)使用字符串自身的split方法;
2)使用JDK的 StringTokenizer工具类;
3)使用Spring/ Apache commons-lang 等工具包中的工具类;
4)自己可以利用indexOf 方法写一个分割工号类;
75、字符串工具类isEmpty 和 isBlank的区别?
isEmpty和isBlank到底有啥区别?1) isEmpty
判断字符串是否为空字符串,只要有一个任意字符(包括空白字符)就不为空。
来看isEmpty的方法源码:
public static boolean isEmpty(Char Sequence c){
return c = null || c.length() == 0;
}
看见没,这个方法只判断了是为为null或者长度为0。
意味着,如果用户输入" ” 等空白字符,这个方法就不通过了,结果就是不为空了。
如验证输入以下内容:
2、isBlank
判断字符串是否为空字符串,全部空白字符也为空。
来看isBlank的方法源码:
isEmpty和isBlank怎么选?
很明显,我们要判断一个字符串为空,绝大部分情况下“空白字符”也要为空的,严谨来说肯定要用isBlank,虽然isEmpty也可以,但如果在最愈端的接口不被拦截掉,请求到了后端的服务、数据库,就可能会造成压力,甚至是系统异常,这是完全可以避免的。
但万事也没有绝对,如果你的程序可以接受任意字符,包括“空白字符”,那就要选择isEmpty,isBlank 会拦截所有空白字符,就达不到要求。所以,这两个工具方法你会用了吗?
与之相对应的一般还有isNotEmpty和isNotBlank,这都是对工具类的封装。
76、Stringeuffer和stringBuilder的区别?
77、StringBuilder,StringBuffer默认容量大小?
默认都是16个字节
扩容大小都是为原来的 2 倍 + 2 个字节
78、Java中的main方法有什么用?
main方法是Java程序的入口方法,JVM在运行的时候会首先查找main方法。.
79、怎么向main方法传递参数?
通过一个 String 数组:
80、不用main方法如何运行一个类?
不行,没有main方法我们不能运行Java类。在Java7之前,你可以通过使用静态初始化运行Java类。但是,从 Java7开始就行不通了。
81、Java所有类的祖先类是哪个?
Java所有类的祖先类是:java.lang.Object类,Java中每个类都是由它拓展而来。
82、Object类有哪些常用的方法?
Object类所有方法如下:
83、普通类和抽象类有什么区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法。
抽象类不能直接通过new实例化,只能通过子类继承,或者通过匿名内部类进行实例化,普通类可以直接new 实例化。
84、静态内部类和普通内部类有什么区别?
静态内部类(Static Nested Class),它可以不依赖于外部类实例被实例化,而普通的内部类需要在外部类实例化后才能实例化。
非静态内部类对象的创建要依赖其外部类对象,也就是说如果没有所谓的外部类对象,就无法创建内部类对象,如果要在静态方法中创建内部类对象、可以这样做:
new Outer().new lnner();
85、静态方法可以直接调用非静态方法吗?
不可以,静态方法只能直接调用静态方法。
因为非静态方法的调用需要先创建对象,而调用静态方法不需要对象实例化。
86、静态变量和实例变量有什么区别?
静态变量:即被 static 修饰的变量、它属于类,但不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝,静态变量可以实现让多个对象共享内存。
实例变量:属于某一对象的实例,需要通过一个类的对象实例才能访问他。
87、内部类可以访问其外部类的成员吗?
可以的、内部类可以访问创建它的外部类对象的成员、包括私有成员。
88、接口和抽象类有什么区别?
区别1:
首先抽象类是一个“类”,而接口只是一个“接口”,两者的概念和应用场景不一样,这也是抽象类和接口的主要区别。
区别2:
即使在Java8中接口也能写实现方法了,但却不能写构造方法,而在抽象类是可以写构造方法的、意味着抽象类是参与类的实例化过程的,而接口则是。
区别3:
抽象类可以有自己的各种成员变量,并且可以通过自己的非抽象方法进行改变,而接口中的变量默认全是public static final修饰的,意味着都是常量,并且不能被自己和外部修改。
区别4:
接口可以实现多继承,而抽象类只能单继承。下面我举两个例子:
类与类只能单继承,而类与接口、接口与接口可以多继承。
总结
Java 8中的接口和抽象类的区别除了接口中可写实现方法之外这点变化,其他的还是保持不变的。
既然接口可以写方法实现了,那么抽象类的存在貌似是弱化了,因为类只能是单继承,耦合性不好,而接口可以多实现,可以灵活扩展,也不会增加类的耦合性。
89、抽象类必须要有抽象方法吗?
不需要,抽象类不一定非要有抽象方法。
示例代码:
abstract class Javastack{
public static void test(){
System.out.println("嘟嘟");
}
}
上面的示例,抽象类并没有抽象方法也可以正常运行。
90、抽象类能使用final修饰吗?
不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类。
91、抽象类是否可以继承具体类?
抽象类可以继承普通类,也可以继承抽象类。
92、抽象类是否可以实现接口?
抽象类可以实现 (implements) 接口。
93、如何判断一个对象是某类、接口的实例?
使用 instanceof 关键字。
User:用户基类
PrivateUser:私人用户子类,继承User类
94、如何判断两个类或者接口之间的派生关系?
使用类的 isAssignableFrom 方法。
User:用户基类
PrivateUser:私人用户子类,继承User类
95、Java创建对象,除了new关键字,你还知道哪些?
去微信收藏看去吧
96、Java怎么生成随机数?
Java 提供了 3 种生成随机数的方法:
1、Math.random
2、java.util.Random
3、java.util.concurrent.ThreadLocalRandom
97、equals和 hashcode的区别和联系?
关于hashCode和 equals方法是有一些常规协定
1、两个对象用equals()比较返回true,那么两个对象的hashCode()方法必须返回相同的结果。
2、两个对象用equals()比较返回false,不要求hashCode()方法也一定返回不同的值,但是最好返回不同值,以提搞哈希表性能。
3、重写equals()方法,必须重写hashCode()5法,以保证equals方法相等时两个对象hashcode返回相同的值。
98、两个对象的equals方法相等,hashcode方法也会相等吗?
一定
根据 java 通用约定,两个对象 equals 相等,则它们的 hashCode 必须相等。
99、两个对象的 hashcode方法相等,equals方法也会相等吗?
不一定
因为在散列表中,hashCode 相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。
100、为什么重写equals 就要重写hashcode?
我们先来看一下Object.hashCode的通用约定(摘自《Effective Java》第45页)
1.在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,那么,对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,这个整数可以不同,即这个应用程序这次执行返回的整数与下一次执行返回的整数可以不一致。
2.如果两个对象根据equals(Object)方法是相等的,那么调用这两个对象中任一个对象的hashCode方法必须产生同样的整数结果。
3.如果两个对象根据equals(Object)方法是不相等的,那么调用这两个对象中任一个对象的hashCode方法,不要求必须产生不同的整数结果。然而,程序员应该意识到这样的事实,对于不相等的对象产生截然不同的整数结果,有可能提高散列表(hash table)的性能。
如果只重写了equals方法而没有重写hashCode方法的话,则会违反约定的第二条:相等的对象必须具有相等的散列码(hashCode) 。
**同时对于HashSet和 HashMap这些基于散列值(hash)实现的类。**HashMap的底层处理机制是以数组的方法保存放入的数据的(Node<K,V>[]table),其中的关键是数组下标的处理。数组的下标是根据传入的元素hashCode方法的返回值再和特定的值异或决定的。
如果该数组位置上已经有放入的值了,且传入的键值相等则不处理,若不相等则覆盖原来的值,如果数组位置没有条目,则插入,并加入到相应的链表中。检查键是否存在也是根hashCode值来确的。所以如果不重写hashCode的话,可能导致HashSet、HashMap不能正常的运作。
如果我们将某个自定义对象存到HashMap或者HashSet及其类似实现类中的时候,**如果该对象的属性参与了hashCode的计算,那么就不能修改该对象参数hashCode计算的属性了。**有可能会移除不了元素,导致内存泄漏。
101、Math.round(1.5)等于多少?
2
因为在数轴上取值时,中间值(0.5)向右取整,所以 0.5 是往上取整。
102、Math.round(-1.5)等于多少?
-1
因为在数轴上取值时,中间值(0.5)向右取整,所以正 0.5 是往上取整,负 0.5 是直接舍弃。
103、Java有没有goto关键字?
goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。
104、Java中有没有指针的概念?
java 中没有指针的概念,指针是 c 和 c++ 里面的概念。
在Java 中,指针已经被其他语法所取代,学习起来更加轻松。
105、Java中的classpath环境变量作用?
classpath 环境变量的作用是用于指定类的搜索路径。
106、判断两个数字两否相等
以上代码的输出结果是?
true
false