什么时候才相等?

对于基础类型来说,值相等则相等。

int a =3;
int b = 3;
System.out.println("a==b is " + (a==b));
//a==b is true

对于对象来说,“==”比较的其实是对象的引用,如果要比较两个对象是否相等,应该用.equals()。

Integer a = 3;
Integer b = 3;
Integer c = b;
System.out.println("a==b is " + (a==b));
System.out.println("c==b is " + (c==b));
System.out.println("a equals b is " + (a.equals(b)));
//a==b is false
c==b is true
a equals b is true

如果,把对象的类型由Integer改为自定义的类型呢?例如:

class TOT {
    private int i;
    TOT (int i){
        this.i = i;
    }
}
public class Main{
  public static void main(String[] args) {
    TOT a = new TOT(3);
    TOT b = new TOT(3);
    System.out.println("a equals b is " + a.equals(b));
  }
}
//a equals b is false

为什么呢?还记得前面说的吗,对象之间.equals是调用了类的equals方法,class TOT继承自是Object,并且未覆盖equals方法,所以比较的时候还是使用的Object类的equals方法,而该方法使用对象的”引用”,显然不相等。

public class Object {
    public boolean equals(Object obj) {
        return (this == obj);
    }

那应该怎么做才能让二者.equals相等呢?很简单,覆盖equals方法。

class TOT {
    private int i;
    TOT (int i){
        this.i = i;
    }
    @Override
    public boolean equals(Object obj) {
        TOT tot = (TOT)obj;
        return this.i == tot.i;
    }
}
public class Main{
  public static void main(String[] args) {
    TOT a = new TOT(3);
    TOT b = new TOT(3);
    System.out.println("a equals b is " + a.equals(b));
  }
}
//a equals b is true

static的用法?

准则:所有的static操作都发生在类加载时。 1、用于修饰类域(静态变量)

class x {
  static int var1;
  int var3;
}

静态成员的存储是独立于类的对象的,换句话说就是,该类所有对象的静态成员引用的是同一块内存(共享)。因此,无论是直接使用类名+变量名(如x.var1 = 1)来修改值,还是使用对象名+变量名(new x().var = 1),更新的都是同一块内存,会互相影响。

2、用于修饰类的方法(静态方法) static method实际是一些没有传入this引用的特殊方法,用户可以不经过new 对象就调用该方法。静态方法不能调用类的非静态方法,也无法访问非静态变量(没有this 指针)。

3、静态代码块 类定义时,可以将静态变量的处理放到类的静态代码块中,该代码块会在类初始化之前调用,所以如果给main类的静态代码块,会在main入口之前先执行,因为main入口执行之前,需要先加载main类。

public class Main {
    static {
        System.out.println("Static Code");
    }
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
//Static Code
//Hello World!

需要注意一种特殊情况:static修饰的集合引用。

static ArrayList<String>  a = new ArrayList<String>();

这时,a作为引用,可以其引用的容器添加对象,并且各个对象、类是同一个容器,需要注意多线程的冲突问题。

this是什么

this是对本对象的引用。几种用法:

1、访问本对象的域,防止与方法的局部变量重名。

2、初始化对象。构造方法只能在构造方法中调用,且必须开始就调用,且只能调用一次。

public class X {
    String str;
    public X() {
        this("a test");
    }
    public X(String str) {
        this.str = str;
    }
}

3、将本对象传递给其他方法。

public class X {
    public void test () {
        System.out.println(this);
    }
    @Overwrite
    public String toString() {
        return "X"
    }
}

类的字段是否会自动初始化?局部变量呢?如果局部变量没有初始化,是编译报错,还是运行随机值呢?

会,不会,编译。跟C不一样,Java会尽量保证程序的安全。

main方法为什么要加static修饰字?

否则谁去new它呢。main方法调用本类内部的方法,该方法也需要为static

如何理解CLASSPATH?

指导解释器在哪些目录下查找.class文件。例如代码中import cn.datastart.debug.Debug,那么解释器会在CLASSPATH指定的所有路径下查找./cn/datastart/debug/Debug.class,找不到则会报错。

注意,jar包略有不同,如果要加到CLASSPATH的话需要带上jar包的名字(很好理解,jar包是多个.class打包而成,可以理解为一个压缩以后的目录)

java的权限设置有哪几种?他们的权限大小关系是?

public、包访问权限、protect、private。默认处于同一目录下的文件之间自动携带包访问权限。其范围关系:

public > protect > 包访问权限 > private

java的权限设置是针对谁的?是否可以设置类的权限?

针对类和类的成员,即域和方法。

可以设置类的权限,但类只有public和包访问权限。一个java文件最多有一个public类,该类全局可见。若不加public则表 包访问权限,即包内可见。

类不存在protect和private权限,但是可以通过设置类的构造器的权限,来间接设置类的private/protect权限。例如:

package cn.datastart.debug;
public class Debug {
   private Debug() {}

如果构造器不加任何修饰符,则表示为包访问权限,那么在包cn.datastart.debug之外的代码中就无法new cn.datastart.debug.Debug;如果加上private,则表示谁都无法new该类的对象,那怎么用呢?可以给该类加一个public方法,在该方法中调用构造器,即,单例。

package cn.datastart.debug;
public class Debug {
    public private Debug() {  }
     public static Debug getDebugInstance() {
        return new Debug();
    }

注意该方法一定是static,否则没有实例怎么调用呢。

64位机器上的int变量,是几个字节?

4个字节。java的int长度是固定的,与cpu是32位还是64位无关。

protected关键字用来做什么?

有些方法需要跨包使用,但又不想像public一样谁都可以用,可以用protected关键字允许继承该类的子类内访问。