注:资料有书为证,大伙可放心翻阅并熟记,由本人亲自总结!
1、Java具有以下几个方面的优点!
①、Java为纯面向对象的语言。
②、Java具有平台无关性。
③、Java提供了很多内置的类库。
④、Java提供了对web应用开发的支持。
⑤、Java具有较好的安全性和健壮性。⑥Java中去除了c++语言中难以理解、容易混淆的特性,使得程序更加严谨、简洁。
拓展:C++语言时一种静态数据类型检查的、支持多重编程范式的通用程序设计语言,它支持过程程序设计、数据抽象、面向对象程序设计、泛型程序设计等多种程序设计风格。
2、Java与C/C++有什么异同?
同:Java与C++都是面向对象语言!
异:①、Java为解释性语言,而C++则为编译性语言。Java的执行速度比C++要慢,但是Java能够跨平台执行,而C++不能。
②、Java为纯面向对象语言,所有代码必须在类中实现。而C++兼具面向过程和面向对象两种特点。
③、Java中没有指针的概念,这有效的防止了操纵指针时可能会引起的系统问题,从而使程序更加安全。
④、Java不支持多重继承,但它引入了接口,可以通过接口来实现多重继承的效果。
⑤、Java提供了垃圾回收器来实现垃圾的自动回收,不再需要程序显式地管理内存的分配…(不止五种!)
拓展:【Java语言中的方法必定隶属于某一个类(对象),调用方法与过程或函数相同。】类和对象的区别在于,对象是需要手动创建的。静态方法是类的成员(类名.方法名),非静态方法是对象的成员(对象名.方法名)。
3、为什么需要public static void main(String[] args)?
它是Java程序的入口方法,JVM在运行程序时,会先查找main()方法。
其中,public是权限修饰符,表明任何类或者对象都可以访问这个方法。
static表明main()方法是一个静态方法,即方法中的代码是存储在静态存储区的。
void表明方法没有返回值,main是JVM识别的特殊方法名。
字符串数组参数args为开发人员在命令行状态下在程序交互提供了一种手段。
拓展:mian()方法还有其他定义格式,例如public和static可以交换位置,也可以把main()方法定义为final、可以用synchronized来修饰main()方法,但不能用abstract关键字来修饰。同一个Java文件中可以有多个main()方法,但是只有与文件名相同的用public修饰的类中的main()方法才能作为整个程序的入口方法。
4、如何实现在main()方法执行前输出!
在Java语言中,由于静态块在类被加载时就会被调用,因此可以在main()方法执行前,利用静态块实现输出。
public class Test{
static{
System.out.println("hello world!"); //这样就可以实现在main()方法之前执行了
}
public static void main(String[] args){
System.out.println("hello world2!")
}
}
5、Java程序初始化的顺序是怎样的?
Java程序初始化遵循的三个原则:
①、静态对象(变量)优先于非静态对象(变量)初始化,其中,静态对象(变量)只初始化一次,而非静态对象(变量)可能会初始化多次。
②、父类优先于子类进行初始化。
③、按照成员变量的定义顺序进行初始化。即使它散布在方法之中,它也会先于方法(包括构造函数)被调用的时候进行初始化。
**Java程序初始化执行顺序:**父类静态变量>>>父类静态代码块>>>子类静态变量>>>子类静态代码块>>>父类非静态变量>>>父类非静态代码块>>>父类构造函数>>>子类非静态变量>>>子类非静态代码块>>>子类构造函数。
6、Java中的作用域有哪些?
**成员变量:**当类被实例化的时候,成员变量才会在内存中分配空间并初始化,生命周期随着实例化对象消亡而消亡。
**静态变量:**被static修饰的成员变量称作静态变量,只要一个类被加载,JVM就会给类的静态变量分配存储空间。因此,可以通过类名和变量名来访问静态变量。
**局部变量:**一般作用域与可见性为它所在的花括号。
具体成员变量四种作用域可见下表:
作用域与可见性 | 当前类 | 同一package | 子类 | 其他package |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
拓展:上述修饰符只能修饰成员变量,不能修饰局部变量。private与protected不能用来修饰外部类(只有public、abstract和final能用来修饰外部类),但它们可以用来修饰内部类。
7、一个Java文件中是否可以定义多个类?
可以,但最多只能有一个类被publi修饰,并且这个类的名字要与文件名相同。使用javac进行编译的时候,会给每一个类生成.class文件。
8、什么是构造函数?
**构造函数:**一种特殊函数,用在对象实例化时初始化对象的成员变量。
构造函数特点:
①、它必须与类的名字相同,且不能有返回值(包括void也不行)。
②、每个类可以有多个构造函数。
③、它可以有0个、1个或1个以上的参数。
④、它总是伴随着new操作一起调用,且不能由程序的编写者直接调用,必须由系统调用。
⑤、它的主要作用完成对象的初始化。
⑥、它不能被继承,因此,它不能被覆盖,但它能够被重载。
⑦、子类可以通过super关键字来显式地调用父类的构造函数,当父类没有提供无参构造时,子类的构造函数中必须显式地调用父类的构造函数。实例对象时先执行父类构造函数然后再执行子类构造函数。
⑧、父类子类都没定义构造函数时,编译器会为父类生成一个默认的无参构造,给子类也声称一个默认的无参构造。
拓展:普通方法可以与构造函数有相同的方法名。
9、为什么Java中有些接口没有任何方法。
接口是抽象方法定义的集合(也可以定义一些常量值),用来克服Java单继承的缺点。
接口中的成员作用域修饰符是public,常量值则默认使用public static final修饰。
接口中没有任何方法的接口被叫做标识接口,它仅仅充当一个标识的作用。
Java类库中已存在的标识接口有Serializable和Cloneable,在使用的时候我们会经常用instanceof来判断实例对象的类型是否实现一个给定的标识接口。
10、Java中的clone方法有什么用?
Java再处理基本数据类型时,采用的是(传递的输入参数的复制)的方式执行,除此之外的其他类型都是按引用传递(传递的是对象的一个引用,虽然也会用到复制,但输入参数复制的是引用对象的地址值,而改变的确实应用对象的内容)的方式执行。
对象除了在函数调用时是引用传递,在使用“=”赋值时也采用了引用传递。
clone()方法返回的时一个Object对象的复制,这个复制函数返回的是一个新的对象而不是一个引用。
使用clone()的步骤:
①、实现clone的类首先需要继承Cloneable接口。
②、在类中重写Object类中的clone()方法。
③、在clone方法中调用super.clone()。无论clone类的继承结构是什么,super.clone()都会直接或间接调用java.lang.Object类中的clone()方法。
④、把浅复制的引用指向原型对象新的克隆体。
如果类中只有一些基本的数据类型时,采用浅复制的方法就可以了,但是当类中包含了一些对象时,就需要用到深复制。实现方法时在对对象调用clone()方法完成复制后,接着对对象中非基本类型也调用clone()方法完成深复制。
拓展:浅复制和深复制有什么区别?
浅复制仅仅复制所考虑的对象,而不复制它所引用的对象;深复制则是把复制的对象锁引用的对象也复制了一边,不单单只是复制了所考虑的对象。
11、什么是反射机制?
反射机制能够实现在***运行时*** 对类进行装载,因此能够增加程序的灵活性,但是不恰当地使用反射机制,也会严重影响系统的性能。
反射机制提供的功能主要有:得到一个对象所属的类;获取一个类的所有成员变量和方法;在***运行时*** 创建对象;在***运行时*** 调用对象的方法。
获取Class类的方法有三种,如下:
1)、Class.forName(“类的路径”)
2)、类名.Class
3)、实例.getClass()
拓展:Java创建对象的方式有四种!
①、通过new语句实例化一个对象。②、通过反射机制创建对象。③、通过clone()方式复制一个新的对象。④、通过反序列化的方式创建对象。
12、package有什么用?
package主要有以下两个作用:第一,提供多层命名空间,解决命名冲突。第二,对类功能进行分类,使项目的组织更加清晰。
13、如何实现类似于C语言中函数指针的功能?
函数指针最重要的功能是实现回调函数!
回调函数是指函数在某处注册,而它将在稍后某个需要的时候被调用。回调函数一般用来获取消息、获取系统信息或处理异步事件。
在Java中实现回调函数,具体就是先定义一个接口,然后在接口中声明要调用的方法,接着就具体实现这个接口,最后把这个实现类的某个对象作为参数传递给调用程序,调用程序通过这个参数来调用指定的函数,从而实现回到函数的功能。(换言之,这段话转换成Java语言如下)
interface IntCompare{
public int cmp(int a,int b);
}
class Cmp1 implements IntCompare{
public int cmp(int a,int b){
if(a>b)
return 1;
else if(a<b)
return -1;
else
return 0;
}
}
class Cmp2 implements IntCompare{
public int cmp(int a,int b){
if(a>b)
return -1;
else if(a<b)
retun 1;
else
return 0;
}
}
public class Test{
public static void insertSort(int[] a,IntCompare cmp){
if(a != null){
for(int i=1; i<a.length; i++){
int temp=a[i];
int j=i;
if(cmp.cmp(a[j-1],temp)==1){
while(j>=1&&cmp.cmp(a[j-1],temp)==1){
a[j]=a[j-1];
j--;
}
}
a[j]=temp;
//到了这里的j应该永远都会处在0,只有这样才会把从后面排上来的值放到a[0]位置。
}
}
}
public static void main(String[] args){
int[] arr1 = {7,3,19,40,4,7,1};
insertSort(arr1,new Cmp1());
Sysem.out.println("升序表列:");
for(int i =0,i<arr1.length,i++)
System.out.print(arr1[i]+" ");
System.out.println();
int[] arr2 = {7,3,19,40,4,7,1};
insertSort(arr2,new Cmp2());
Sysem.out.println("升序表列:");
for(int i =0,i<arr2.length,i++)
System.out.print(arr1[i]+" ");
}
}
拓展:这里的升序和降序排列运用到了策略模式!
转载麻烦请附录地址,感谢大家配合!!!
https://blog.csdn.net/HOLLOWYANG/article/details/119982894