目录
5. hashCode()介绍,为什么要有 hashCode,hashCode 与 equals (重要)
10. 在Java中定义一个不做事且没有参数的构造方法的作用
11. break ,continue ,return 的区别及作用
12. static的注意事项,应用场景,独特之处,存在的主要意义
18. 构造器(constructor)是否可被重写(override)?
24. Java 中操作字符串都有哪些类?它们之间有什么区别?
28. Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
32. 什么是Java程序的主类?应用程序和小程序的主类有何不同?
【写在前面】
此文题目和答案都非原创。
是搜集了网络上分享的关于Java面试常见问题汇总,然后又逐个搜寻了答案,整理于此。
供自学,感谢相关题目和答案的原创分享者。
1. JDK动态代理和CGLIB动态代理的区别
1.1代理模式:
代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法、实际执行的是被代理类的方法。AOP是通过动态代理实现的。
1.2 两者区别:
JDK动态代理只能对实现了接口的类生成代理,而不能针对类
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承)
1.3 Spring在选择用JDK还是CGLiB的依据:
1)当Bean实现接口时,Spring就会用JDK的动态代理
2)当Bean没有实现接口时,Spring使用CGlib是实现
3)可以强制使用CGlib(在spring配置中加入
<aop:aspectj-autoproxy proxy-target-class="true"/>)
1.4 两者效率比较
1)使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
2)在对JDK动态代理与CGlib动态代理的代码实验中看,1W次执行下,JDK7及8的动态代理性能比CGlib要好20%左右。
2. 静态代理和动态代理的区别
2.1 静态代理
创建一个接口 -> 然后创建被代理的类实现该接口并且实现该接口中的抽象方法 >之后再创建一个代理类,同时使其也实现这个接口。在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法, 做一些加工处理(代理功能)。
静态代理的本质:
由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
2.2 动态代理
动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
2.3 区别
(1)静态代理在程序运行前就已经存在代理类的字节码文件,并确认了代理类和委托类的关系;
(2)动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。 动态代理根据接口或目标对象,计算出代理类的字节码,然后再加载到JVM中使用。
其实现原理如下:由于JVM通过字节码的二进制信息加载类的,那么,如果我们在运行期系统中,遵循Java编译系统组织.class文件的格式和结构,生成相应的二进制数据,然后再把这个二进制数据加载转换成对应的类,这样,就完成了在代码中动态创建一个类的能力了。
(3)静态代理的缺点是在程序规模稍大时,维护代理类的成本高,静态代理无法胜任;
(4)动态代理只能为了实现接口的类创建代理。
3. ArrayList和LinkedList有什么区别?
3.1 数据结构不同
ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。
3.2 效率不同
(1)当随机访问List(get和set操作)时, ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
(2)当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。【视频教程推荐:Java视频教程】
3.3 自由性不同
(1)ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;
(2)而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。
3.4 主要控件开销不同
(1)ArrayList主要控件开销在于需要在lList列表预留一定空间;
(2)而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。
4. Java 8的接口新增了哪些特性?
在jdk1.8以前接⼝中,只能有抽象方法,不能有任何方法的实现(方法体)。
而在jdk1.8中打破常规,接口添加静态方法和默认方法。
引入了新的关键字default,在接口中使default修饰的方法,可以在接口编写方法体。实现了该接口的类,可以直接调用接口的默认方法。
可直接使用 接口名.静态方法 来调用接口中的静态方法。(如:Animal.run();)
5. hashCode()介绍,为什么要有 hashCode,hashCode 与 equals (重要)
(1)equals()用于判断两个对象是否相等,这是大家公认的。
hashCode()被设计是用来使得哈希容器能高效的工作。
(2)在Java中,有一些哈希容器,比如Hashtable,HashMap等等。当我们调用这些容器的诸如get(Object obj)方法时,容器的内部肯定需要判断一下当前obj对象在容器中是否存在,然后再进行后续的操作。一般来说,判断是否存在,肯定是要将obj对象和容器中的每个元素一一进行比较,要使用equals()才是正确的。
(3)但是如果哈希容器中的元素有很多的时候,使用equals()必然会很慢。这个时候用替代方案hashCode():当我们调用哈希容器的get(Object obj)方法时,它会首先利用查看当前容器中是否存在有相同哈希值的对象,如果不存在,那么直接返回null;如果存在,再调用当前对象的equals()方法比较一下看哈希处的对象是否和要查找的对象相同;如果不相同,那么返回null。如果相同,则返回该哈希处的对象。
(4)hashCode()返回一个int类型,两个int类型比较起来要快很多。
(5)hashCode()被设计用来使得哈希容器能高效的工作。也只有在哈希容器中,才使用hashCode()来比较对象是否相等,但要注意这种比较是一种弱的比较,还要利用equals()方法最终确认。
(6)hashCode()相等看成是两个对象相等的必要非充分条件,把equals()相等看成是两个对象相等的充要条件。因此,在自定义一个类时,必须要同时重写equals()和hashCode(),并且必须保证:
其一:如果两个对象的equals()相等,那么他们的hashCode()必定相等。
其二:如果两个对象的hashCode()不相等,那么他们的equals()必定不等。
6. 什么是方法的返回值?返回值的作用是什么?
返回值常用的有String,int,boolean等, 一个方法就是实现一个功能。
而那个返回值就是方法执行完后返回的那个结果(也就是我们需要的)。
通常调用一个方法要么让它完成某项功能,要么就是获得它的返回值。
7. 静态方法和实例方法有何不同?
(1)静态方法:在加载类时就加载静态方法,在外部调用静态方法时,可使用 " 类名.方法名 " 的方式,也可使用 "对象名.方法名 "的方式。而实例方法只有"对象名.方法名 "方式。即调用静态方法可以无需创建对象。实例方法在调用时才被加载。
(2)静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制 .
8. 静态变量和实例变量区别
(1)静态变量:独立存在的变量,只是位置放在某个类下,可以直接“类名.静态变量名”使用。并且是项目或程序一启动运行到该类时就直接常驻内存。不需要初始化类再调用该变量。用关键字static声明。静态方法也是同样,可以直接调用。
(2)实例变量:相当于该类的属性,需要先初始化该类,就是new 出对象后,才可以通过对象调用。但是该对象未被再次使用,被垃圾回收器回收后,该实例也将不存在了,即不在内存中了。
区别如下:
1)存储区域不同:静态变量存储在静态存储区,普通变量存储在堆中;
2)静态变量与类相关,实例变量则与实例相关
3)内存分配方式不同。
4)生命周期不同。
9. 构造方法有哪些特性?
特点:
(1)构造方法名一定与类同名。
(2)构造方法无返回值类型(void也不行)
(3)构造方法可以没有(默认一个无参构造方法),也可以有多个构造方法。他们之间构成重载关系。
(4)如果定义有参构造函数,则默认的无参构造函数将被自动屏蔽。
(5)构造方法不能被继承。
(6)构造方法不能手动调用,在创建类实例的时候自动调用构造方法。
作用:
(1)初始化对象,为对象赋初值。
(2)简化我们为类字段赋值的代码。
构造方法和普通方法的区别:
(1)构造方法一定与类同名,普通方法就可以不用。
(2)构造方法无返回值类型(void也不行),普通方法可以返回。
10. 在Java中定义一个不做事且没有参数的构造方法的作用
Java 程序在执行子类的构造方法之前,如果没有用 super() 来显式调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。
因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用 super() 来调用父类中特定的构造方法,则编译时将发生错误,因为 Java 程序在父类中找不到没有参数的构造方法可供执行。
解决办法是在父类里加上一个不做事且没有参数 的构造方法。
11. break ,continue ,return 的区别及作用
(1)作用不同
break:执行break操作,跳出所在的当前整个循环,到外层代码继续执行。
continue:执行continue操作,跳出本次循环,从下一个迭代继续运行循环,内层循环执行完毕,外层代码继续运行。
return:执行return操作,直接返回函数,所有该函数体内的代码(包括循环体)都不会再执行。
(2)结束不同
break:break不仅可以结束其所在的循环,还可结束其外层循环,但一次只能结束一种循环。
continue:continue结束的是本次循环,将接着开始下一次循环。
return:return同时结束其所在的循环和其外层循环。
(3)紧跟不同
break:需要在break后紧跟一个标签,这个标签用于标识哪个外层循环。
continue:在continue后不需要加参数。
return:在return后需要紧跟一个返回值,用于提供给对应方法所需的返回值。
12. static的注意事项,应用场景,独特之处,存在的主要意义
(1)注意事项
1)在静态方法中是没有this关键字的
静态是随着类的加载而加载,this是随着对象的创建而存在。静态比对象先存在。
2)静态方法只能访问静态的成员变量和静态的成员方法
静态方法:成员变量只能访问静态变量,成员方法:只能访问静态成员方法
非静态方法:成员变量可以是静态的也可以是非静态的,成员方法可以是静态的成员方法,也可以是非静态的成员方法。
(2)应用场景
因为static是被类的实例对象所共享,因此如果某个成员变量是被所有对象所共享的,那么这个成员变量就应该定义为静态变量。比较常见的static应用场景有:修饰成员变量,修饰成员方法,静态代码块,修饰类【只能修饰内部类也就是静态内部类】,静态导包
(3)独特之处
1)被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享。即一个类的静态成员,它是属于大伙的所有的类对象共享的,不像成员变量是自个的(单个实例对象)。
2)在该类被第一次加载时,就会去加载被static修饰的部分,而且只在类第一次使用时加载并进行初始化,注意这是第一次用就要初始化,后面根据需要是可以再次赋值的。
3)static变量值在类加载时分配空间,以后创建类对象的时候不会重新分配。赋值的话,是可以任意赋值的!
4)被static修饰的变量或者方法是优先于对象存在的,也就是说当一个类加载完毕之后,即便没有创建对象,也可以去访问。
(4)存在的主要意义:
static的主要意义是在于创建独立于具体对象的域变量或者方法。以至于即使没有创建对象,也能使用属性和调用方法!
还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
13. this与super的区别
(1)属性的区别:this访问本类中的属性,如果本类没有此属性则从父类中继续查找。super访问父类中的属性。
(2)方法的区别:this访问本类中的方法,如果本类没有此方法则从父类中继续查找。super访问父类中的方法。
(3)构造的区别:this调用本类构造,必须放在构造方法的首行。super调用父类构造,必须放在子类构造方法首行。
(4)其他区别:
this表示当前对象。super不能表示当前对象
1)this. 变量和super.变量
this.变量 调用的当前对象的变量;
super.变量 直接调用的是父类中的变量。
2)this(参数)和super(参数)方法
this(参数) 调用(转发)的是当前类中的构造器;
super(参数) 用于确认要使用父类中的哪一个构造器。
14. super关键字的用法
(1)在子类的成员方法中,访问父类的成员变量。
(2)在子类的成员方法中,访问父类的成员方法。
(3)在子类的构造方法中,访问父类的构造方法。
15. String类的常用方法有哪些?
length():求字符串的长度
indexOf():求某个字符在字符串中的位置
charAt():求一个字符串中某个位置的值
equals():比较两个字符串是否相同
replace():将字符串中的某些字符用别的字符替换掉。形如 replace(“abc”,”ddd”);
字符串中的 abc 将会被 ddd 替换掉。
split():根据给定正则表达式的匹配拆分此字符串。形如 String s = “The time is going quickly!”;
str1=s.split(" ");
substring():输出一个新的字符串,它是此字符串中的子串,形如 substring(3,7);
它将字符串中的第四个 截取 第五个第六个输出。
trim():将字符串开头的空白(空格)和尾部的空白去掉。
format():使用指定的语言环境、格式字符串和参数返回一个格式化字符串。
toLowerCase():将字符串中所有的大写改变成小写
toUpperCase():将字符串中所有的小写改变为大写
getBytes():获取字符串字节数组
16. char型变量中能否能不能存储一个中文汉字,为什么
char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中可以存储汉字。
不过,如果某个特殊的汉字没有被包含在unicode 编码字符集中,那么,这个char型变量中就不能存储这个特殊的汉字。
unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。
17. 是否可以继承String类?
不可以,String类是一个最终类,被final修饰,所以不能被继承。
18. 构造器(constructor)是否可被重写(override)?
首先,构造器是不能被继承的,因为每个类的类名都不相同,而构造器名称与类名相同,所以根本谈不上继承。又由于构造器不能继承,所以就不能被重写。但是,在同一个类中,构造器是可以被重载的。
不能重写但是可以重载,因为构造方法不能被继承。
如果在子类的构造方法中,没有使用关键字super调用父类的某个构造方法,那么默认有super();语句,即调用父类不带参数的构造方法。
如果类里定义一个或多个构造方法,那么java不提供默认的构造方法(不带参数的构造方法)。因此,当在父类中定义多个构造方法时,应当包括一个不带参数的构造方法,以防子类省略super时出现错误。
19. 谈谈你对多态的理解?
多态,是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编
程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,
该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到
各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以
改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
多态性
增强了软件的灵活性和扩展性。
20. Java中实现多态的机制是什么?
20.1 本质上多态分两种:
(1)编译时多态(又称静态多态):重载(overload)就是编译时多态的一个例子,编译时多态在编译时就已经确定,运行时运行的时候调用的是确定的方法。
(2)运行时多态(又称动态多态):我们通常所说的多态指的都是运行时多态,也就是编译时不确定究竟调用哪个具体方法,一直延迟到运行时才能确定。这也是为什么有时候多态方法又被称为延迟方法的原因。
20.2 多态通常有两种实现方法:
(1)子类继承父类(extends)
(2)类实现接口(implements)
无论是哪种方法,其核心之处就在于对父类方法的改写或对接口方法的实现,以取得在运行时不同的执行效果。
要使用多态,在声明对象时就应该遵循一条法则:声明的总是父类类型或接口类型,创建的是实际类型。虚拟机会在执行程序时动态调用实际类的方法,它会通过一种名为动态绑定(又称延迟绑定)的机制自动实现,这个过程对程序员来说是透明的。
21. new一个对象的过程和clone一个对象的区别?
(1)new对象
new操作符的本意是分配内存,程序执行 到new操作时,首先去看new操作符后面的类型,因为知道了类型才能知道要分配多大的内存空间。
分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把它引用(地址)发布到外部,在外部就可以使用这个引用操作这个对象。
(2)clone
clone在第一步和new相似,都是分配内存,调用clone方法时,分配的内存和原对象(即调用clone方法的对象)相同。
然后再使用原对象中对应的各个域,填充新对象的域,填充完成后,clone方法返回,一个新的对象被创建,同样可以把这个新对象的引用发布到外部。
22. 深克隆和浅克隆?
(1)为什么要克隆?
克隆的对象可能包含一些已经修改过的属性,保留着你想克隆对象的值,而new出来的对象的属性全是一个新的对象,对应的属性没有值,所以我们还要重新给这个对象赋值。即当需要一个新的对象来保存当前对象的“状态”就靠clone方法了。
那么我把这个对象的临时属性一个一个的赋值给我新new的对象不也行?可以是可以,但是一来麻烦不说,二来,大家通过上面的源码都发现了clone是一个native方法,就是快啊,在底层实现的。
(2)如何实现克隆,分三步:
对象的类实现Cloneable接口;
覆盖Object类的clone()方法 (覆盖clone()方法,访问修饰符设为public,默认是protected);
在clone()方法中调用super.clone();
(3)两种不同的克隆方法,浅克隆(ShallowClone)和深克隆(DeepClone)。
浅克隆:是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
深克隆:不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
23. Java中为什么要用 clone?
在实际编程过程中,我们常常要遇到这种情况:有一个对象 A,在某一时刻 A 中已经包含了一些有效值,此时可能会需要一个和 A 完全相同新对象 B,并且此后对 B 任何改动都不会影响到 A 中的值,也就是说,A 与 B 是两个独立的对象,但 B 的初始值是由 A 对象确定的。
在 Java 语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求虽然有很多途径,但clone()方法是其中最简单,也是最高效的手段。
24. Java 中操作字符串都有哪些类?它们之间有什么区别?
24.1 CharSequence 接口有三个实现类与字符串有关:String、StringBuffer、StringBuilder
虽然它们都与字符串有关,但是其处理机制是不同的。
(1)String 类是不可改变的量,也就是创建后就不能再修改了,比如创建了一个“abc”这样的字符串对象,那么它在内存中永远都会是“abc”这样具有固定表面值的一个对象,不能被修改,即使想通过 String 提供的方法来尝试修改,也是要么创建一个新的字符串对象,要么返回自己
(2)StringBuffer 是一个可变字符序列,它与 String 一样,在内存中保存的都是一个有序的字符序列(char 类型的数组),不同点是 StringBuffer 对象的值是可改变的。
(3)StringBuilder 与 StringBuffer 基本相同,都是可变字符序列,不同点是:StringBuffer 是线程安全的,StringBuilder 是线程不安全的,翻翻两者的源代码,就会发现在 StringBuffer 的方法前都有 synchronized 关键字,这也是 StringBuffer 在性能上远低于 StringBuilder 的原因。
24.2 在性能方面,由于 String 类的操作都是产生新的 String 对象,而 StringBuilder 和 StringBuffer 只是一个字符数组的再扩容而已,所以 String 类的操作要远慢于 StringBuffer 和 StringBuilder。
24.3 在不同的场景下使用不同的字符序列:
(1)使用 String 类的场景
在字符串不经常变化的场景中可以使用 String 类,例如常量的声明、少量的变量运算等。
(2)使用 StringBuffer 类的场景
在频繁进行字符串的运算(如拼接、替换、删除等),并且运行在多线程的环境中,则可以考虑使用 StringBuffer,例如 XML 解析、HTTP 参数解析和封装等。
(3)使用 StringBuilder 类的场景
在频繁进行字符串的运算(如拼接、替换、删除等),并且运行在单线程的环境中,则可以考虑使用 StringBuilder,如 SQL 语句的拼装、JSON 封装等。
24.4 三者区别
(1)String 是字符串常量,而 StringBuffer 和 StringBuilder 是字符串变量。由 String 创建的字符内容是不可改变的,而由 StringBuffer 和 StringBuidler 创建的字符内容是可以改变的。
(3)StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的。StringBuilder 是从 JDK 5 开始,为 StringBuffer 类补充的一个单线程的等价类。我们在使用时应优先考虑使用 StringBuilder,因为它支持 StringBuffer 的所有操作,但是因为它不执行同步,不会有线程安全带来额外的系统消耗,所以速度更快。
25. Java有哪些数据类型
Java中的数据类型分为两大类分别是基本类型和引用类型,基本类型包含int,float,double,char,boolean等八种类型,引用类型包含类,数组,接口三种类型。
26. 什么是Java注释
(1)定义:用于解释说明程序的文字
(2)分类
单行注释
格式: // 注释文字
多行注释
格式: /* 注释文字 */
文档注释
格式:/** 注释文字 */
(3)作用:在程序中,尤其是复杂的程序中,适当地加入注释可以增加程序的可读性,有利于程序的修改、调试和交流。注释的内容在程序编译的时候会被忽视,不会产生目标代码,注释的部分不会对程序的执行结果产生任何影响。
27. 用最有效率的方法计算2乘以8?
2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。
28. Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
(1)四舍五入。
(2)round()方法可以这样理解:
将括号内的数+0.5之后,向下取值,
比如:round(3.4)就是3.4+0.5=3.9,向下取值是3,所以round(3.4)=3;
round(-10.5)就是-10.5+0.5=-10,向下取值就是-10,所以round(-10.5)=-10
所以,Math.round(11.5)=12;
现在再来看,Math.round(11.5),Math.round(-11.5)你应该知道等于多少了吧,掌握了方法就好解决问题了。
29. &和&&的区别?
29.1 相同点:&和&&都可以用作逻辑与的运算符,表示逻辑与(and)。
29.2 不同点:
(1)&&具有短路的功能,而&不具备短路功能。
(2)当&运算符两边的表达式的结果都为true时,整个运算结果才为true。而&&运算符第一个表达式为false时,则结果为false,不再计算第二个表达式。
(3)&还可以用做位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如:0x31 & 0x0f的结果为0x01。
30. 访问修饰符public,private,protected,以及不写(默认)时的区别?
31. Java语言有哪些特点
(1) 简单性:
Java语言是C++语言的一个“纯净”版本。没有头文件、指针运算、结构、联合、操作符重载、虚基类等。
(2)面向对象:
面向对象即面向数据。Java的面向对象特性与C++旗鼓相当,Java与C++的主要不同点在于多继承,在Java中,取而代之的是更简单的接口概念。
(3)分布式:
Java有一个丰富的例程库,用于处理像HTTP和FTP之类的TCP/IP协议。Java应用程序能够通过URL打开和访问网络上的对象,其便捷程度就像访问本地文件一样。
(4)健壮性:
Java编写的程序具有多方面的可靠性。Java编译器能够检测许多在其他语言中仅在运行时才能检测出来的问题。
(5)安全性:
Java适用于网络/分布式环境。从一开始,Java程序能够防范各种攻击,其中包括:
运行时堆栈溢出。
破坏自己进程空间之外的内存。
未经授权读写文件。
(6)体系结构中立:
编译器生成一个体系结构中立的目标文件格式,这是一种编译过的代码,只要有Java运行时系统,这些编译后的代码可以在许多处理器上运行。Java编译器通过生成与特定的计算机体系结构无关的字节码指令来实现这一特性。
(7)可移植性:
例:Java中的int永远为32位的整数,而C/C++中,int可能是16位整数、32位整数,也可能是编译器提供商指定的其他大小。这样的优点便消除了代码移植的问题。
(8)解释型
Java解释器可以在任何一只了解释器的机器上执行Java字节码。
(9)高性能
字节码可以(在运行时刻)动态地翻译成对应运行这个应用特定CPU的机器码。
(10)多线程
多线程可以带来更好的交互响应和实时行为。如今大家非常关注并发性,我们不在追求更快的处理器,而是更多的处理器,Java是第一个支持并发的主流语言。
(11)动态性
库中可以自由地添加新方法和实例变量,而对客户段没有任何影响。
32. 什么是Java程序的主类?应用程序和小程序的主类有何不同?
(1) 一个程序中可以有多个类,但只能有一个类是主类。
(2) 在Java应用程序中,这个主类是指包含main()方法的类。
(3) 而在Java小程序中,这个主类是一个继承自系统类JApplet或Applet的子类。
(4) 应用程序的主类不一定要求是public类,但小程序的主类要求必须是public类。
(5) 主类是Java程序执行的入口点。
33. 说下面向对象四大特性
(1)抽象
忽略一个主题中与当前目标无关的东西,专注的注意与当前目标有关的方面.(就是把现实世界中的某一类东西,提取出来,用程序代码表示,抽象出来的一般叫做类或者接口).抽象并不打算了解全部问题,而是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一个数据抽象,而是过程抽象.
数据抽象 -->表示世界中一类事物的特征,就是对象的属性.比如鸟有翅膀,羽毛等(类的属性)
过程抽象 -->表示世界中一类事物的行为,就是对象的行为.比如鸟会飞,会叫(类的方法)
(2)封装
封装就是把过程和数据包围起来,对数据的访问只能通过特定的界面.如私有变量,用set,get方法获取
(3)继承
一种联结类的层次模型,并且允许和鼓励类的重用,提供一种明确表达共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始类的派生类(子类),原始类称为新类的基类(父类).派生类可以从它的父类哪里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要.因此可以说,继承为了重用父类代码,同时为实现多态性作准备.
(4)多态
多态是指允许不同类的对象对同一消息做出响应.多态性包括参数化多态性和包含多态性.多态性语言具有灵活/抽象/行为共享/代码共享的优势,很好的解决了应用程序函数同名问题.总的来说,方法的重写,重载与动态链接构成多态性.java引入多态的概念原因之一就是弥补类的单继承带来的功能不足.
动态链接 -->对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将调用子类中的这个方法,这就是动态链接.