1.java语言是由C++语言改进并重新设计而来的。
2.java语言中的方法属于类中的成员(number)?
错误:
在java中,方法分为静态方法和非静态方法。
静态方法是类成员,非静态方法是实例成员。
3.为什么需要public static void main(String[] args) {}这个方法?
是java程序的入口方法,其他定义格式:
1)public与static没有先后关系static public void main(String[] args) {}
2)也可以把main方法定义为final:public static final void main(String[] args) {}
3)也可以用synchronized来修饰main方法public static synchronized void main(String[] args) {}
4.实现在main()方法执行前输出“Hello World”?
package com.zcl.test;
public class Test {
static{
System.out.println("Hello World1");
}
public static void main(String[] args) {
System.out.println("Hello World!");
}
static{
System.out.println("Hello World2");
}
}
5.java程序初始化的顺序?
父类静态变量,父类静态代码块,子类静态变量,子类静态代码块
父类非静态变量,父类非静态代码块,父类构造函数
子类非静态变量,子类非静态代码块,子类构造函数
例1:
package com.zcl.test;
class Base{
static{
System.out.println("Base static block");
}
{
System.out.println("Base block");
}
public Base(){
System.out.println("Base constructor");
}
}
public class Derived extends Base {
static{
System.out.println("Derived static block");
}
{
System.out.println("Derived block");
}
public Derived(){
System.out.println("Derived constructor");
}
public static void main(String[] args) {
new Derived();
}
}
结果:
Base static block
Derived static block
Base block
Base constructor
Derived block
Derived constructor
例2:
package com.zcl.test;
public class Testclass {
public static void main(String[] args) {
new A();
}
}
class B extends Object{
static{
System.out.println("Load B1");
}
public B(){
System.out.println("Create B");
}
static{
System.out.println("Load B2");
}
}
class A extends B{
static{
System.out.println("Load A");
}
public A(){
System.out.println("Create A");
}
}
结果:
Load B1
Load B2
Load A
Create B
Create A
6.java中的作用域?
java中变量有三种:成员变量,静态变量,局部变量
其中成员变量有四种作用域
需要注意的是:
这些修饰符只能修饰成员变量,不能修饰局部变量;
private和protected不能用来修饰类
只有public,abstract,final可以用来修饰类
实例方法可以直接调用其他类的实例方法|超类的实例方法和类方法吗?
当其他类或者超类被private修饰时不能调用。
7.一个java文件中可以定义多个类,但是只能有一个类被public修饰,并且这个类的类名与文件名必须相同。
8.构造函数的作用是在对象实例化时初始化对象的成员变量。
普通方法也可以与构造方法有相同的方法名。
9.为什么java中有些接口没有任何方法?
没有任何方法声明的接口称为标识接口,用来表示实现它的类属于一个特定的类型。
例如Cloneable和Serializable
在使用时候经常用instanceof来判断实例对象的类型是否实现了一个给定的标识接口。
例1:要开发一款游戏,游戏里有一个人物专门负责寻找有用的材料,假设这个任务只收集武器和矿石,不会收集垃圾,下面通过标识接口来实现这个功能。
package com.zcl.test;
import java.util.ArrayList;
interface Stuff{}
//矿石
interface Ore extends Stuff{}
//武器
interface Weapon extends Stuff{}
//垃圾
interface Rubbish extends Stuff{}
//金矿
class Gold implements Ore{
public String toString() {
return "Gold";
}
}
//铜矿
class Copper implements Ore{
public String toString() {
return "Copper";
}
}
//枪
class Gun implements Weapon{
public String toString() {
return "Gun";
}
}
//榴弹
class Grenade implements Weapon{
public String toString() {
return "Grenade";
}
}
//石头
class Stone implements Rubbish{
public String toString() {
return "Stone";
}
}
public class Test {
public static ArrayList<Stuff> collectStuff(Stuff[] s){
ArrayList<Stuff> al = new ArrayList<>();
for (int i = 0; i < s.length; i++) {
if(!(s[i] instanceof Rubbish)){
al.add(s[i]);
}
}
return al;
}
public static void main(String[] args) {
Stuff[] s = {new Gold(),new Copper(),new Gun(),new Grenade(),new Stone()};
ArrayList<Stuff> collectStuff = collectStuff(s);
System.out.println("The usefull Stuff collected is:");
for (Stuff stuff : collectStuff) {
System.out.println(stuff);
}
}
}
10.java中clone方法的作用?
例1:java中对象和引用的区别?
java在处理基本数据类型时,都是按值传递,其他类型都是引用传递
对象除了在函数调用时是引用传递,在使用“=”赋值时也采用引用传递
package com.zcl.test;
class Obj{
private String str = "default value";
public void setStr(String str) {
this.str = str;
}
public String toString() {
return str;
}
}
public class TestRef {
private Obj aObj = new Obj();
private int aInt = 0;
public Obj getaObj() {
return aObj;
}
public int getaInt() {
return aInt;
}
public void changeObj(Obj inObh){
inObh.setStr("change value");
}
public void changeInt(int inInt){
inInt = 1;
}
public static void main(String[] args) {
TestRef oRef = new TestRef();
System.out.println("=========引用类型============");
System.out.println("调用changeObj之前:"+oRef.getaObj());
oRef.changeObj(oRef.getaObj());
System.out.println("调用changeObj之后:"+oRef.getaObj());
System.out.println("=========基本数据类型============");
System.out.println("调用changeInt之前:"+oRef.getaInt());
oRef.changeInt(oRef.getaInt());
System.out.println("调用changeInt之后:"+oRef.getaInt());
}
}
结果:
=========引用类型============
调用changeObj之前:default value
调用changeObj之后:change value
=========基本数据类型============
调用changeInt之前:0
调用changeInt之后:0
例2:
package com.zcl.test;
class Obj{
private int aInt = 0;
public int getaInt() {
return aInt;
}
public void setaInt(int aInt) {
this.aInt = aInt;
}
public void changeInt(){
this.aInt = 1;
}
}
public class TestRef {
public static void main(String[] args) {
Obj a = new Obj();
Obj b = a;
b.changeInt();
System.out.println("a:"+a.getaInt());
System.out.println("b:"+b.getaInt());
}
}
结果:
a:1
b:1
使用clone方法的步骤:
1)实现clone的类首先需要继承Cloneable接口
2)在类中重写Object类中的.clone方法
3)在clone方法中调用super.clone()
4)把浅复制的引用指向原型对象新的克隆体
对上面的例子引入clone方法如下:
例3:
package com.zcl.test;
class Obj implements Cloneable{
private int aInt = 0;
public int getaInt() {
return aInt;
}
public void setaInt(int aInt) {
this.aInt = aInt;
}
public void changeInt(){
this.aInt = 1;
}
protected Object clone(){
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
public class TestRef {
public static void main(String[] args) {
Obj a = new Obj();
Obj b = (Obj) a.clone();
b.changeInt();
System.out.println("a:"+a.getaInt());
System.out.println("b:"+b.getaInt());
}
}
结果:
a:0
b:1
当类中只有一些基本的数据类型时,采用上述方法就可以;
当类中包含一些对象时,就需要用到深复制;
实现方法是在对对象调用clone()方法完成复制之后,接着对对象中的非基本类型的属性也调用clone方法完成深复制。
例4:
package com.zcl.test;
import java.util.Date;
class Obj implements Cloneable{
private Date birth = new Date();
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public void changeBirth(){
this.birth.setMonth(3);
}
protected Object clone(){
Obj o = null;
try {
o = (Obj) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
//实现深复制
o.birth = (Date) this.getBirth().clone();
return o;
}
}
public class TestRef {
public static void main(String[] args) {
Obj a = new Obj();
Obj b = (Obj) a.clone();
b.changeBirth();
System.out.println("a="+a.getBirth());
System.out.println("b="+b.getBirth());
}
}
结果:
a=Mon May 21 15:29:20 CST 2018
b=Sat Apr 21 15:29:20 CST 2018
原型模式(Prototype)中就需要clone一个对象实例
11.什么是反射机制?
反射允许程序在运行时进行自我检查,同时也允许对其内部的成员进行操作,能够实现在运行时对类进行装载。
反射机制提供的功能:
1)得到一个对象所属的类
2)获取一个类的所有成员变量和方法
3)在运行时创建对象(主要)
4)在运行时调用对象的方法
例1:在运行时动态地创建类的兑现
package com.zcl.test;
class Base{
public void f(){
System.out.println("Base");
}
}
class Sub extends Base{
public void f(){
System.out.println("Sub");
}
}
public class Test {
public static void main(String[] args) {
try {
Class c = Class.forName("com.zcl.test.Sub");
Base b = (Base) c.newInstance();
b.f();
} catch (Exception e) {
e.printStackTrace();
}
}
}
在反射机制中,如何获取Class类呢?
1)Class.forName("类的路径")
2)类名.Class
3)实例.getClass()
java创建对象的方式有哪几种?
1)通过new语句实例化一个对象
2)通过反射机制创建对象
3)通过clone方法创建一个对象
4)通过反序列化的方式创建一个对象
12.package有什么作用?
1)提供多层命名空间,解决命名冲突
2)对类按功能进行分类,使项目的组织更加清晰
13.如何实现类似于C语言中函数指针的功能?
函数指针最重要的功能是实现回调函数
即函数先在某处注册,而它将在稍后某个需要的时候被调用
例:程序员张三写了一段程序a,其中预留有回调函数接口,并封装好了该程序。程序员李四要让a调用自己的程序b中的一个方法,于是他通过a中的接口回调属于自己的程序b中的那个方法。
例:在实现排序算法时,可以通过传递一个函数指针来决定两个数的先后顺序,从而最终决定该算法是按升序还是降序排列。
具体而言:先定义一个接口,然后在接口中声明要调用的方法,接着实现这个接口,最后把这个实现类的一个对象作为参数传递给调用程序,调用程序通过这个参数来调用指定的函数,从而实现回调函数的功能。
package com.zcl.test;
//接口中定义了一个用来比较大小的方法
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) {
return 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],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;
}
}
}
public static void main(String[] args) {
int[] array1 = {7,3,19,40,4,7,1};
insertSort(array1, new Cmp1());
System.out.println("升序排列");
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i]+" ");
}
int[] array2 = {7,3,19,40,4,7,1};
insertSort(array2, new Cmp2());
System.out.println();
System.out.println("降序排列");
for (int i = 0; i < array2.length; i++) {
System.out.print(array2[i]+" ");
}
}
}
结果:
升序排列
1 3 4 7 7 19 40
降序排列
40 19 7 7 4 3 1
策略设计模式所用思想