11、“==”和“equal”方法究竟有什么区别
如下编码所示,相同的字符串,两次不同的声明,分配的地址不一样。除非编译器有优化。
package somethingelse;
public class StringSameOrNot {
public static void main(String[] args)
{
String a = new String("hello");
String b = new String("hello");
String c = a;
if(a==c)
System.out.println("a==c");
if(a==b)
System.out.println("== is true");
if(a.equals(b))
System.out.println("equal is true");
}
}
如下编码所示,一个启动类、一个包含static的A类,两个实例化A类的类被启动类实例化。观察static的类变量是否会相互影响值。
session 一般为20分钟的 自动释放 程序结束释放
application iis 或硬件重启 会释放
static 程序结束就会释放
启动类每次执行,static变量都会被释放,重新从0开始算。但是启动类内的static变量是累计叠加的。
package somethingelse;
public class TestStatic {
public static void main(String[] args)
{
TestStaticA a = new TestStaticA();
TestStaticB b = new TestStaticB();
a.changeStatic();
a.changeStatic();
b.changeStatic();
}
}
package somethingelse;
public class TestStaticA {
public TestStaticA()
{
}
public void changeStatic(){
IncludingStatic.a++;
System.out.println("a=" + IncludingStatic.a);
}
}
package somethingelse;
public class TestStaticB {
public TestStaticB()
{
}
public void changeStatic(){
IncludingStatic.a++;
System.out.println("a=" + IncludingStatic.a);
}
}
package somethingelse;
public class IncludingStatic {
public static int a = 0;
public IncludingStatic()
{
// a++;
// System.out.println("a="+a);
}
}
18、overload和override的区别。
package somethingelse;
class Base{
public String book = "abc";
}
class Derived extends Base{
public int book = 12;
}
public class TestExtend{
protected int i = 10;
public int ii = 20;
public static void main(String[] agrs) {
Base b = new Derived();
System.out.println(b.book);
}
}
父类和子类的构造方法的继承
当子类没有override构造方法的时候,默认调用父类的non-argument的构造方法。如果写了non-argument的构造方法,没写super();编译器默认调用一次父类的构造方法,再执行子类的构造方法。如果子类写了super(argument-list),则不再执行non-argument的父类构造方法,而是执行指定的父类带argument的构造方法。
20、接口是否可以继承接口?抽象类是否可以实现implement接口?抽象类是否可以继承具体类?抽象类是否可以有static的main方法?
ps:
1、Java只允许单继承,不允许多继承。但是,可以多implement接口。因为,继承是属性,一个class只能是一种东西,相反,接口是定义了行为,不同东西可以有相同的行为,例如跑这个动作,哺乳动物里面,马和猴子都具有,但是属于不同的类。
2、抽象类是否可以实现接口? ( 注意,此处是实现,而不能是继承,因为接口没有构造函数。)
换而言之,接口的方法是否必须被实现。
如果子类是非抽象类,则必须实现接口中的所有方法;
如果子类是抽象类,则可以不实现接口中的所有方法,因为抽象类中允许有抽象方法的存在!
答案是不一定的。但是实现类必须标明是abstract类以显示其还有未实现的方法,譬如
public abstract class B implements A{
public B(){
}
}
这样,就可以保证不能new B(); 而是通过B b = new C();
3、抽象类是否可以继承具体类。
一道Java 常见面试题,网上找到的几乎每个 java 面试笔试题大全或集锦里都能找到这道题。
题目如下:
问: 抽象类是否可继承实体类 (concrete class)
答: 抽象类是可以继承实体类,但前提是实体类必须有明确的构造函数
答案很明确,可以继承。其实从Object就是个实体类,java的API文档里,每个抽象类的条目里都明确写着直接或间接继承自Object,所以这点是没有疑问的。
关键在于这答案里所说的“前提是实体类必须有明确的构造函数”一句,是什么意思。
一般学习者会写的简单试验代码:
class A{}
abstract class B extends A{}
结果完全正常,编译通过。似乎和“实体类必须有明确的构造函数”完全没有关系。
这个问题涉及到两个个基础知识:
1.
所有的class都必须有一个构造方法,如果你没有在代码里声明构造方法,系统会自动给你生成一个公有无参的构造方法。而只要你自己声明了一个构造方法,无论有参无参,私有公有,系统就不再帮你生成默认无参构造器了。
2.
所有的子类构造器都要求在第一行代码中调用父类构造器,如果不写,系统默认去调用父类的无参构造器。
所以,如果把系统默认配给的方法也算进去,class A{}的代码实际上是
class A{
public A(){}
}
B继承 A 的时候,则是
abstract class B extends A{
public B(){
super();
}
}
要试验出这继承规则的内部情况,也很简单,在最上面那个简单试验代码里,加上个私有构造器,有参无参都行。
class A{
private A(){}
}
这个时候,如基础知识(1) 中所说,系统不再给你默认无参构造器, B的构造器根据(2)中的规则去调用super(),却找不到A的无参构造器,所以导致abstract class B extends A{} 编译不能通过。(因为A中没有任何构造器可供子类调用,其实这个时候A只能够供内部类继承,我用的Eclipse的3.4版本会建议给B改名,但是这解决不了这个问题。)
现在,你应该了解了资料给的那句语焉不详的“实体类必须有明确的构造函数”的含义:
1.没写构造器的,那是拥有默认无参公有构造函数的,子类可以什么都不写,让默认构造器去调用它。这是最初那两行代码的情况。
2.写了子类可访问的无参构造器的,也是一样,子类里可以什么都不写,用默认机制调用。
3.写了 有参构造器却没写无参构造器的,父类里没有子类可访问的无参构造器,子类必须在子类构造器里的第一句写明,调用父类有参构造器,并把参数传进去。
4.声明为final的以及所有构造器都不在子类访问权限之内的类无法继承
其实只要是在类的继承中,无论抽象还是实体,都需要符合这个规则的。在这个继承试验中随时删掉或是加上abstract的前缀,结果都没有变化。个人觉得“实体类必须有明确的构造函数”一句实在是无法把这个情况表达清楚,所以广大求职者还是写得清楚些好。
我喜欢的写法是“可以继承,但是和实体类的继承一样,也要求父类可继承,并且拥有子类可访问到的构造器。”
我笔试的时候只答的“可以继承”。心想所有的类都从Object类继承吧,掉了后半句。
4、抽象类是否可以有static的main方法?
可以。