JAVA基础常见面试

JAVA面试集锦

简述JDK、JRE、JVM

一、JDK 
JDK(Java Development Kit) 是整个JAVA的核心,
包括了Java运行环境(Java Runtime Envirnment),
一堆Java工具(javac/java/jdb等)
和Java基础的类库(即Java API 包括rt.jar)。 
JDK是java开发工具包,
基本上每个学java的人都会先在机器 上装一个JDK,
那他都包含哪几部分呢?
在目录下面有 六个文件夹、
一个src类库源码压缩包、
和其他几个声明文件。
其中,真正在运行java时起作用的
 是以下四个文件夹:bin、include、lib、 jre。
有这样一个关系,JDK包含JRE,而JRE包 含JVM。 
bin:最主要的是编译器(javac.exe) 
include:java和JVM交互用的头文件 
lib:类库 
jre:java运行环境 

二、JRE 
JRE(Java Runtime Environment,Java运行环境)
包含JVM标准实现及Java核心类库。
JRE是Java运行环境,并不是一个开发环境,
所以没有包含任何开发工具(如编译器和调试器) 
JRE是指java运行环境。
光有JVM还不能成class的 执行,
因为在解释class的时候
JVM需要调用解释所需要的类库lib。 (
jre里有运行.class的java.exe) 
JRE ( Java Runtime Environment ),
是运行 Java 程序必不可少的
(除非用其他一些编译环境编译成.exe可执行文件……)
JRE的 地位就象一台PC机一样,
我们写好的Win64应用程序需要操作系统帮 我们运行,
同样的,我们编写的Java程序也必须要JRE才能运行。

三、JVM 
JVM(Java Virtual Machine),
即java虚拟机, java运行时的环境,
JVM是一种用于计算设备的规范,
它是一个虚构出来的计算机,
是通过在实际的计算机上仿真模拟
各种计算机功能来实现的。
针对java用户,
也就是拥有可运行的.class文件包(jar或者war)的用户。
里面主要包含了jvm和java运行时基本类库(rt.jar)。
rt.jar可以简单粗暴地理解为:
它就是java源码编译成的jar包。
Java虚拟机在执行字节码时,
把字节码解释成具体平台上的机器指令执行。
这就是Java的能够“一次编译,
到处运行”的原因。

JDK、JRE、JVM三者有什么联系和区别?

1.三者联系:
JVM不能单独搞定class的执行,
解释class的时候JVM需要调用解释所需要的类库lib。
在JDK下面的的jre目录里面
有两个文件夹bin和lib,
在这里可以认为bin里的就是jvm,
lib中则是jvm工作所需要的类库,
而jvm和 lib和起来就称为jre。
JVM+Lib=JRE。
总体来说就是,
我们利用JDK(调用JAVA API)开发了属于
我们自己的JAVA程序后,
通过JDK中的编译程序(javac)
将我们的文本java文件编译成JAVA字节码,
在JRE上运行这些JAVA字节码,
JVM解析这些字节码,
映射到CPU指令集或OS的系统调用。

2.三者区别: 
JDK和JRE区别:
在bin文件夹下会发现,
JDK有javac.exe而JRE里面没有,
javac指令是用来将java文件编译成class文件的,
这是开发者需要的,
而用户(只需要运行的人)是不需要的。
JDK还有jar.exe, javadoc.exe等等
用于开发的可执行指令文件。
这也证实了一个是开发环境,
一个是运行环境。 
b.JRE和JVM区别:
JVM并不代表就可以执行class了,
JVM执行.class还需要JRE下的lib类库的支持,
尤其是rt.jar。

简述Java程序编译和运行的过程?

Java程序从源文件创建到程序运行要经过两大步骤:
1、源文件由编译器编译成字节码(ByteCode); 
2、字节码由java虚拟机解释运行。
因为java程序既要编译同时
也要经过JVM的解释运行,
所以说Java被称为半解释语言

在这里插入图片描述

第一步(编译):
创建完源文件之后,
程序先要被JVM中的java编译器
进行编译为.class文件。
java编译一个类时,
如果这个类所依赖的类还没有被编译,

编译器会自动的先编译这个所依赖的类,
然后引用。
如果java编译器在指定的目录下
找不到该类所依赖的类的 .class文件
或者 .java源文件,
就会报"Cant found sysbol"的异常错误。

编译后的字节码文件格式
主要分为两部分:
常量池和方法字节码。
常量池记录的是代码出现过的
(常量、类名、成员变量等)
以及符号引用(类引用、方法引用,成员变量引用等);
方法字节码中放的是各个方法的字节码。

第二步(运行):
java类运行的过程大概分为两个步骤:
(1)类的加载 
(2)类的执行。
需要说明的一点的是:
JVM主要在程序第一次运行时主动使用类的时候,
才会立即去加载。
换言之,
JVM并不是在运行时就会把所有使用到的类
都加载到内存中,
而是用到,不得不加载的时候,
才加载进来,而且只加载一次!

请说出八种基础数据类型及字节大小?

1. byte                  82. short                163. int                  324. long                 645. float                326. double               647. boolean               18. char                 16

说说&和&&的区别?

&&&都是逻辑运算符,
都是判断两边同时真则为真,否则为假;
但是&&当第一个条件不成之后,
后面的条件都不执行了,
而&则还是继续执行,
直到整个条件语句执行完为止。

float型float f=3.4是否正确?

:
不正确;
精度不准确,
应该用强制类型转换,
如下所示:float f=(float)3.4 

short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?

short s1 = 1; s1 = s1 + 1; s1+1
运算结果是int型,
需要强制转换类型; 

short s1 = 1; s1 += 1;
可以正确编译,自动类型提升。

int 和 Integer 有什么区别?

Java 提供两种不同的类型:
引用类型和原始类型(或内置类型);
int是java的原始数据类型,
Integer是java为int提供的封装类。 

引用类型和原始类型的行为完全不同,
并且它们具有不同的语义。
引用类型和原始类型具有不同的特征和用法,

它们包括:大小和速度问题,
这种类型以哪种类型的数据结构存储,

当引用类型和原始类型
用作某个类的实例数据时所指定的缺省值。

对象引用实例变量的缺省值为 null,
而原始类型实例变量的缺省值
与它们的类型有关。

在JAVA中,如何跳出当前的多重嵌套循环?

在最外层循环前加label标识,
然后用break:ok 方法即可跳出多重循环。
ok:
    for(int i=0;i<10;i++)    {
        for(int j=0;j<10;j++)  {
            System.out.println(“i=+ i +,j=+ j);
            if(j == 5) break ok;
        }
    } 
for(int i=0;i<4;i++){
                for(int j=0;j<5;j++){
                    System.out.println("i="+i+"; j="+j);
                    if(j==3){
                        i=4;
                        break;
                    }
                }
            }

使用嵌套的for循环打印九九乘法表。

public class test {
    public static void main(String[] args) {
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.print(j + "*" + i + "=" + i * j + " ");
            }
            System.out.println();
        }
    }
}

面向对象的特征有哪些方面

1.抽象:
抽象就是忽略一个主题中与当前目标无关的那些方面,
以便更充分地注意与当前目标有关的方面。
抽象并不打算了解全部问题,而只是选择其中的一部分,
暂时不用部分细节。
抽象包括两个方面,
一是过程抽象,
二是数据抽象。

2.继承:
继承是一种联结类的层次模型,
并且允许和鼓励类的重用,
它提供了一种明确表述共性的方法。
对象的一个新类可以从现有的类中派生,
这个过程称为类继承。
新类继承了原始类的特性,
新类称为原始类的派生类(子类),
而原始类称为新类的基类(父类)。
派生类可以从它的基类那里继承方法和实例变量,
并且类可以修改或增加新的方法使之更适合特殊的需要。

3.封装:
封装是把过程和数据包围起来,
对数据的访问只能通过已定义的界面。
面向对象计算始于这个基本概念,
即现实世界可以被描绘成一系列完全自治、
封装的对象,
这些对象通过一个受保护的接口访问其他对象。
4. 多态性:
多态性是指允许不同类的对象对同一消息作出响应。
多态性包括参数化多态性和包含多态性。
多态性语言具有灵活、抽象、行为共享、代码共享的优势,
很好的解决了应用程序函数同名问题。

java 创建对象的几种方式

采用new

通过反射

采用clone

通过序列化机制

前2者都需要显式地调用构造方法。
造成耦合性最高的恰好是第一种,
因此你发现无论什么框架,
只要涉及到解耦必先减少new的使用。

修饰符public,private,protected,以及不写时的区别

修饰符当前类同一个package子孙类其他package
publicYESYESYESYES
protectedYESYESYESNO
defaultYESYESNONO
privateYESNONONO
不写时默认为friendly/default
friendly权限是java的默认权限,也称作包(package)访问权限
只要不加privatepublic、protect的
就是friendly访问权限,
所有的成员仅限同一个包内的成员访问

String s = new String(“xyz”);创建了几个String Object

两个,一个字符对象,一个字符对象引用对象

Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math.round(11.5)==12;
Math.round(-11.5)==-11;
round方法返回与参数最接近的长整数,
参数加1/2后求其floor

Java有没有goto?

java中的保留字,现在没有在java中使用

Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型

方法的重写Overriding和重载Overloading是Java多态性的不同表现。
重写Overriding是父类与子类之间多态性的一种表现,
重载Overloading是一个类中多态性的一种表现。
如果在子类中定义某方法与其父类有相同的名称和参数,
我们说该方法被重写 (Overriding)。
子类的对象使用这个方法时,
将调用子类中的定义,
对它而言,
父类中的定义如同被"屏蔽"了。
如果在一个类中定义了多个同名的方法,
它们或有不同的参数个数或有不同的参数类型,
则称为方法的重载(Overloading)。
Overloaded的方法是可以改变返回值的类型

abstract class和interface有什么区别

声明方法的存在而不去实现它的类被叫做抽象类(abstract class),
它用于要创建一个体现某些基本行为的类,
并为该类声明方法,
但不能在该类中实现该类的情况。
不能创建abstract 类的实例。

然而可以创建一个变量,
其类型是一个抽象类,
并让它指向具体子类的一个实例。
不能有抽象构造函数或抽象静态方法。
Abstract 类的子类为它们父类中的
所有抽象方法提供实现,
否则它们也是抽象类为。

取而代之,在子类中实现该方法。
知道其行为的其它类可以在类中实现这些方法
接口(interface)是抽象类的变体。

在接口中,所有方法都是抽象的。
多继承性可通过实现这样的接口而获得。
接口中的所有方法都是抽象的,
没有一个有程序体。

接口只可以定义static final成员变量。
接口的实现与子类相似,
除了该实现类不能从接口定义中继承行为。

当类实现特殊接口时,
它定义(即将程序体给予)所有这种接口的方法。
然后,它可以在实现了该接口的类的
任何对象上调用接口的方法。

由于有抽象类,
它允许使用接口名作为引用变量的类型。
通常的动态联编将生效。
引用可以转换到接口类型或从接口类型转换,
instanceof 运算符可以用来
决定某对象的类是否实现了接口

接口是否可继承接口?

接口可以继承接口。
抽象类可以实现(implements)接口,
抽象类是否可继承实体类,但
前提是实体类必须有明确的构造函数

swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上

swtich()里面必须是int和enum--即枚举类型。
short、 char 或者 byte他会自动转换为int的。。
long不能自动转换为int..
因为long比int范围大..可能会丢失精度..

在java的1.7之后的jdk版本,
java中的switch里面表达式的类型可以是string类型,
之前是不可以使用的

final, finally, finalize的区别

1、final修饰符(关键字)。
被final修饰的类,
就意味着不能再派生出新的子类,
不能作为父类而被子类继承。
因此一个类不能既被abstract声明,
又被final声明。将变量或方法声明为final,
可以保证他们在使用的过程中不被修改。
被声明为final的变量必须在声明时给出变量的初始值,
而在以后的引用中只能读取。
被final声明的方法也同样只能使用,
即不能方法重写。

finally是在异常处理时

提供finally块来执行任何清除操作。
不管有没有异常被抛出、捕获,finally块都会被执行。
try块中的内容是在无异常时执行到结束。
catch块中的内容,
是在try块内容发生catch所声明的异常时,
跳转到catch块中执行。
finally块则是无论异常是否发生,
都会执行finally块的内容,
所以在代码逻辑中有需要
无论发生什么都必须执行的代码,
就可以放在finally块中。

3、finalize是方法名。
java技术允许使用finalize()方法
在垃圾收集器将对象从内存中
清除出去之前做必要的清理工作。
这个方法是由垃圾收集器
在确定这个对象没有被引用时对这个对象调用的。
它是在object类中定义的,
因此所有的类都继承了它。
子类覆盖finalize()方法以整理系统资源或者被执行其他清理工作。
finalize()方法是在垃圾收集器
删除对象之前对这个对象调用的。 

###2.Overload和Override的区别。
首先重载和重写是应用于两个不同场景下面的两种不同的手段:
两者各自的特征:
重载(Overload):首先是位于一个类之中或者其子类中,
具有相同的方法名,
但是方法的参数不同,
返回值类型可以相同也可以不同。
(1):方法名必须相同
(2):方法的参数列表一定不一样。
(3):访问修饰符和返回值类型可以相同也可以不同。
其实简单而言:重载就是对于不同的情况写不同的方法。
 比如,同一个类中,
写不同的构造函数用于初始化不同的参数。

重写(override):一般都是表示子类和父类之间的关系,
其主要的特征是:
方法名相同,
参数相同,
但是具体的实现不同。

重写的特征:
(1):方法名必须相同,返回值类型必须相同
(2):参数列表必须相同
(3):访问权限不能比父类中被重写的方法的访问权限更低。
例如:如果父类的一个方法被声明为public,
那么在子类中重写该方法就不能声明为protected。
(4):子类和父类在同一个包中,
那么子类可以重写父类所有方法,
除了声明为privatefinal的方法。
(5):构造方法不能被重写,
简单而言:就是具体的实现类对于父类的该方法实现不满意,
需要自己在写一个满足于自己要求的方法。

Java中的String,StringBuilder,StringBuffer三者的区别?

首先说运行速度,或者说是执行速度,
在这方面运行速度快慢为:StringBuilder > StringBuffer > String
String最慢的原因:
String为字符串常量,
而StringBuilder和StringBuffer均为字符串变量,
即String对象一旦创建之后该对象是不可更改的,
但后两者的对象是变量,是可以更改的。
而StringBuilder和StringBuffer的对象是变量,
对变量进行操作就是直接对该对象进行更改,
而不进行创建和回收的操作,
所以速度要比String快很多。

String               ---->     字符串常量
StringBuffer      ---->     字符串变量(线程安全的)
StringBuilder    ---->     字符串变量(非线程安全的)

String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

GC是什么? 为什么要有GC?

GC是垃圾收集的意思,
内存处理是编程人员容易出现问题的地方,
忘记或者错误的内存回收
会导致程序或系统的不稳定甚至崩溃,
Java提供的GC功能
可以自动监测对象是否超过作用域
从而达到自动回收内存的目的,

Java语言没有提供释放已分配内存的显示操作方法。J
ava程序员不用担心内存管理,
因为垃圾收集器会自动进行管理。
要请求垃圾收集,
可以调用下面的方法之一:
System.gc()或Runtime.getRuntime().gc(),
但JVM可以屏蔽掉显示的垃圾回收调用。 

垃圾回收可以有效的防止内存泄露,
有效的使用可以使用的内存。
垃圾回收器通常是作为一个单独的低优先级的线程运行,
不可预知的情况下对内存堆中
已经死亡的或者长时间没有使用的对象进行清除和回收,
程序员不能实时的调用垃圾回收器
对某个对象或所有对象进行垃圾回收。

Java有了GC,
就不需要程序员去人工释放内存空间。
当Java虚拟机发觉内存资源紧张的时候,
就会自动地去清理无用变量所占用的内存空间。
当然,如果需要,
程序员可以在Java程序中显式地使用System.gc()
来强制进行一次立即的内存清理。

构造器如何工作?

Java在构造实例时的顺序是这样的:
1、分配对象空间,并将对象中成员初始化为0或者空
,java不允许用户操纵一个不定值的对象。   
2、执行属性值的显式初始化   
3、执行构造器   
4 、将变量关联到堆中的对象上

而执行构造器的步骤有可以分为以下几步:

1、Bind构造器的参数
2、如果显式的调用了this,那就递归调用this构造器然后跳到步骤5
3、递归调用显式或者隐式的父类构造器,除了Object以外,因为它没有父类
4、执行显式的实例变量初始化(也就是上边的流程中的第二步,调用返回以后执行,
   这个步骤相当于在父构造器执行后隐含执行的,看样子像一个特殊处理)

构造器Constructor是否可被override?

构造器Constructor不能被继承,
因此不能重写Overriding,
但可以被重载Overloading 
1). 构造器不能是native,final,static,synchronized,
可以是public,private,或什么都没有。 
2). 构造器函数里可以写return,但后面什么都不许有(包括null) 
3). 构造器不能返回值. 
但如果有个"构造器"返值了,
它就不是构造器喽,只是个普通方法 
4). super();this();这两个方法只能在构造方法里调用. 
5). 成员变量声明时候赋值,比构造函数还早.

写一个Singleton出来。

Singleton模式主要作用是保证在Java应用程序中,
一个类Class只有一个实例存在。 
一般Singleton模式通常有几种种形式: 
第一种形式: 定义一个类,
它的构造函数为private的,
它有一个staticprivate的该类变量,
在类初始化时实例话,
通过一个public的getInstance方法获取对它的引用,
继而调用其中的方法。 

public class Singleton { 
  private Singleton(){} 
  //在自己内部定义自己一个实例,是不是很奇怪? 
  //注意这是private 只供内部调用 
  private static Singleton instance = new Singleton(); 
  //这里提供了一个供外部访问本class的静态方法,可以直接访问   
  public static Singleton getInstance() { 
    return instance;    
   } 
} 

第二种形式: 
public class Singleton { 
  private static Singleton instance = null; 
  public static synchronized Singleton getInstance() { 
  //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次      
  //使用时生成实例,提高了效率! 
  if (instance==null) 
    instance=new Singleton(); 
return instance;   } 
} 

其他形式: 
定义一个类,
它的构造函数为private的,
所有方法为static的。 
一般认为第一种形式要更加安全些

error和exception有什么区别?

Error类和Exception类都继承自Throwable类。
二者的不同之处:
Exception:
1.可以是可被控制(checked) 或不可控制的(unchecked)2.表示一个由程序员导致的错误。
3.应该在应用程序级被处理。

Error:
1.总是不可控制的(unchecked)2.经常用来用于表示系统错误或低层资源的错误。
3.如何可能的话,应该在系统级被捕捉。

error 表示恢复不是不可能但很困难的情况下的一种严重问题。
比如说内存溢出。
不可能指望程序能处理这样的情况。 

exception 表示一种设计或实现问题。
也就是说,
它表示如果程序运行正常,
从不会发生的情况。 

HashMap和Hashtable的区别?

hashmap:
1.线程不安全
2.允许有null的键和值
3.效率高一点、
4.方法不是Synchronize的要提供外同步
5.有containsvalue和containsKey方法
6.HashMap 是Java1.2 引进的Map interface 的一个实现
7.HashMap是Hashtable的轻量级实现

hashtable:
1.线程安全
2.不允许有null的键和值
3.效率稍低、
4.方法是是Synchronize的
5.有contains方法方法
6.Hashtable 继承于Dictionary 类
7.Hashtable 比HashMap 要旧

==和equals()区别?

对于==,
如果作用于基本数据类型的变量,
则直接比较其存储的 
“值”是否相等;
如果作用于引用类型的变量,
则比较的是所指向的对象的地址

对于equals方法,
注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,
则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,
比较的是所指向的对象的内容。

静态变量和实例变量的区别?

静态变量也叫类变量,
这种变量前加了static修饰符。
可以直接用类名调用,
也可以用对象调用,
而且所有对象的同一个类变量 
都是共享同一块内存空间。

实例变量也叫对象变量,
这种变量没有加static修饰符。
只能通过对象调用, 
而且所有对象的同一个实例变量
是共享不同的内存空间的。

区别在于:
静态变量是所有对象共有的,
某一个对象将它的值改变了,
其他对象再去获取它的值,
得到的是改变后的值;
实例变量则是每一个对象私有的,
某一个对象将它的值改变了,
不影响其他对象取值的结果,
其他对象仍会得到实例变量
一开始就被赋予的值。

实例变量必须创建对象后
才可以通过这个对象来使用,
静态变量
则可以直接使用类名来引用。

垃圾回收器的基本原理是什么?

垃圾回收器是Java平台中用的
最频繁的一种对象销毁方法。
垃圾回收器会全程侦测Java应用程序的运行情况。
当发现有些对象成为垃圾时,
垃圾回收器就会销毁这些对象,
并释放这些对象所占用的内存空间。
在这里,程序开发人员需要知道,
在哪些情况下垃圾回收器
会认为这些对象是垃圾对象。
通常情况下,如果发生以下两种情况时,
系统会认为这些对象是垃圾对象,
需要销毁。
一是将一个NULL值赋值给对象。
二是对象其超出了作用范围,

垃圾回收器可以马上回收内存吗?

不会马上回收,
只有在必须回收时才会回收,
或者你可以调用垃圾回收方法,
虚拟机会在空闲时回收,
至于什么时候回收,
虚拟机说了算

有什么办法主动通知虚拟机进行垃圾回收?

对于GC来说,
当程序员创建对象时,
GC就开始监控这个对象的地址、
大小以及使用情况。 
通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。
通过这种方式确定哪些对象是”可达的”,
哪些对象是”不可达的”。
当GC确定一些对象为”不可达”时,
GC就有责任回收这些内存空间。
可以。程序员可以手动执行System.gc(),
通知GC运行,
但是Java语言规范
并不保证GC一定会执行。

System.gc()的工作原理
Java中的内存分配
是随着new一个新的对象来实现的,
这个很简单,
而且也还是有一些
可以“改进”内存回收的机制的,
其中最显眼的
就是这个System.gc()函数。

乍一看这个函数似乎是可以进行垃圾回收的,
可事实并不是那么简单。
其实这个gc()函数的作用只是提醒虚拟机:
程序员希望进行一次垃圾回收。
但是它不能保证垃圾回收一定会进行,
而且具体什么时候进行
是取决于具体的虚拟机的,
不同的虚拟机有不同的对策。

内部类可以引用他包含类的成员吗?

完全可以。
如果不是静态内部类,
那没有什么限制! 
一个内部类对象可以访问
创建它的外部类对象的成员包括私有成员。
如果你把静态嵌套类当作内部类的一种特例,
那在这种情况下不可以访问外部类的
普通成员变量,
而只能访问外部类中的静态成员。

内部类的访问规则:
1、内部类可以直接访问外部类中的成员,
包括私有。
之所以可以直接访问外部类中的成员,
是因为内部类中持有了
一个外部类的引用,
格式 外部类名.this
2、外部类要访问内部类,必须建立内部类对象。

内部类定义在局部时,
1、不可以被成员修饰符修饰
2、可以直接访问外部类中的成员,
因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量。
只能访问被final修饰的局部变量。

Java 中的异常处理机制的简单原理和应用?

一、Execption可以分为
java标准定义的异常
程序员自定义异常21.一种是当程序违反了java语规则的时候,
JAVA虚拟机就会将发生的错误
表示为一个异常.
这里语法规则指的是
JAVA类库内置的语义检查。
例如 int i = 2 / 0 
或者 String str = null;str.length();

2.另一种情况就是JAVA允许程序员
扩展这种语义检查,
程序员可以创建自己的异常,
并自由选择在何时用throw关键字
引发异常。

例如 Exception ex = new Exception("这是我自定义的异常;
throw ex;

所有的异常都是Thowable的子类。
异常处理是与程序执行是并行的。

二、异常的处理方式
1.捕获异常

 try {
  int i = 2 / 0;
 } catch (Exception ex) {
   ex.printStackTrace();
   System.out.println("异常信息:" + ex.getMessage());
}

2.上抛异常 throws
public void test() throws Exception { 
    String str = null;
    str.length();
}

运行时异常与一般异常有何异同?

(1)运行时异常
都是RuntimeException类
及其子类异常,
如NullPointerException、
IndexOutOfBoundsException等,
这些异常是不检查异常,
程序中可以选择捕获处理,
也可以不处理。
这些异常一般是由程序逻辑错误引起的,
程序应该从逻辑角度
尽可能避免这类异常的发生。

当出现RuntimeException的时候,
我们可以不处理。
当出现这样的异常时,
总是由虚拟机接管。
比如:我们从来没有人
去处理过NullPointerException异常,
它就是运行时异常,
并且这种异常还是最常见的异常之一。

出现运行时异常后,
系统会把异常一直往上层抛,
一直遇到处理代码。
如果没有处理块,
到最上层,
如果是多线程就由Thread.run()抛出,
如果是单线程就被main()抛出。
抛出之后,
如果是线程,
这个线程也就退出了。
如果是主程序抛出的异常,
那么这整个程序也就退出了。
运行时异常是Exception的子类,
也有一般异常的特点,
是可以被Catch块处理的。
只不过往往我们不对他处理罢了。
也就是说,
你如果不对运行时异常进行处理,
那么出现运行时异常之后,
要么是线程中止,
要么是主程序终止。 

如果不想终止,
则必须扑捉所有的运行时异常,
决不让这个处理线程退出。
队列里面出现异常数据了,
正常的处理应该是把异常数据舍弃,
然后记录日志。
不应该由于异常数据
而影响下面对正常数据的处理。

(2)非运行时异常
是RuntimeException以外的异常,
类型上都属于Exception类及其子类。
如 IOException、SQLException 等
以及用户自定义的Exception异常。
对于这种异常,
JAVA编译器强制要求我们
必需对出现的这些异常进行catch并处理,
否则程序就不能编译通过。
所以,面对这种异常不管我们是否愿意,
只能自己去写一大堆catch块
去处理可能的异常。

为什么Map接口不继承Collection 接口?

Collection是最基本的集合接口,
声明了适用于JAVA集合(只包括Set和List)
的通用方法。 
Set 和List 都继承了Conllection;
Set具有与Collection完全一样的接口,
因此没有任何额外的功能,
不像前面有两个不同的List。
实际上Set就是Collection,只 是行为不同。
(这是继承与多态思想的典型应用:表现不同的行为。)
Set不保存重复的元素(至于如何判断元素相同则较为负责) 

 Map没有继承于Collection接口 
从Map集合中检索元素时,
只要给出键对象,
就会返回对应的值对象。 


Collection 和 Map 的区别
容器内每个为之所存储的元素个数不同。
Collection类型者,
每个位置只有一个元素。
Map类型者,
持有 key-value pair,
像个小型数据库

尽管Map接口和它的实现也是集合框架的一部分,
但Map不是集合,
集合也不是Map。
因此,Map继承Collection毫无意义,
反之亦然。
如果Map继承Collection接口,
那么元素去哪儿?
Map包含key-value对,
它提供抽取key或value列表集合的方法,
但是它不适合“一组对象”规范。

comparable 和 comparator的不同之处?

Comparable可以认为是一个内比较器,
实现了Comparable接口的类有一个特点,
就是这些类是可以和自己比较的,
至于具体和另一个实现了Comparable接口的类如何比较,
则依赖compareTo方法的实现,
compareTo方法也被称为自然比较方法。
如果开发者add进入
一个Collection的对象想要Collections的sort方法
帮你自动进行排序的话,
那么这个对象必须实现Comparable接口。
compareTo方法的返回值是int,
有三种情况:
1、比较者大于被比较者
(也就是compareTo方法里面的对象),
那么返回正整数
2、比较者等于被比较者,那么返回0
3、比较者小于被比较者,那么返回负整数


Comparator可以认为是是一个外比较器,
个人认为有两种情况
可以使用实现Comparator接口的方式:
1、一个对象不支持自己和自己比较
(没有实现Comparable接口),
但是又想对两个对象进行比较
2、一个对象实现了Comparable接口,
但是开发者认为compareTo方法中的
比较方式并不是自己想要的那种比较方式

Comparator接口里面有一个compare方法,
方法有两个参数T o1和T o2,
是泛型的表示方式,
分别表示待比较的两个对象,
方法返回值和Comparable接口一样是int,
有三种情况:
1、o1大于o2,返回正整数
2、o1等于o2,返回0
3、o1小于o2,返回负整数

总结
两种比较器Comparable和Comparator,
后者相比前者有如下优点:
1、如果实现类没有实现Comparable接口,
又想对两个类进行比较
或者实现类实现了Comparable接口,
但是对compareTo方法内的比较算法不满意,
那么可以实现Comparator接口,
自定义一个比较器,
写比较算法

2、实现Comparable接口的方式比
实现Comparator接口的耦合性要强一些,
如果要修改比较算法,
要修改Comparable接口的实现类,
而实现Comparator的类是在外部进行比较的,
不需要对实现类有任何修 改。
从这个角度说,
其实有些不太好,
尤其在我们将实现类的.class文件
打成一个.jar文件
提供给开发者使用的时候。
实际上实现Comparator 接口的方式
后面会写到就是一种典型的策略模式。

当然,这不是鼓励用Comparator,
意思是开发者还是要在具体场景下
选择最合适的那种比较器而已。
基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip 【备注】 1、该资源内项目代码百分百可运行,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值