static方法:如果接口中要使用static修饰方法,则必须有方法体(java8之后);抽象类的抽象方法无法用static。总结,这种情况方法中能不能用static就想想该方法能不能通过类名.去访问
static变量:接口中使用static变量则必须初始化,因为接口声明的变量默认是public static final的。抽象类使用static变量则可以不用初始化(作为成员变量默认初始化)
abstract class TestAbstract {
static int i;
static abstract void run();//报错,无法使用static
}
interface TestInterface{
static int i;//报错,需要初始化
static void run();//报错,无方法体
}
class TASon extends TestAbstract{
public static void main(String[] args) {
System.out.println(i);//结果为0
}
}
native方法:抽象方法不能被本地方法修饰,本地方法是由本地代码实现的方法(非java代码),即暗示这些方法其实是有方法体的,而抽象方法还没有完成实现,所以抽象方法不能既实现又没实现…
public native int hashCode();//Object中的hashCode方法,虽然没法显式看到方法体,但是native却暗示了方法体的存在
abstract void run();//显然的指明了这个方法无实现体
synchronized方法:抽象方法无法显式的去声明为synchronized,但这并不意味着他不能使用synchronized(或者说并不意味着他不能达到同步的效果),如下面的方法所示,可以看出抽象方法完全可以让自己子类的实现方法去实现同步(如果可以将synchronized显式声明亦如此),但这并不意味着抽象方法“应该”能够同步。它实际上是在锁中调用“未知”代码,这本身就非常危险,这是死锁等的秘诀(总结来说就是不安全?得让编写的人看见方法体才可以写synchronized?)
abstract class TestAbstract {
public synchronized void m() {
print();//如果abstract可以显式声明synchronized的话应该就是这种感觉吧
}
abstract void print();
synchronized abstract void print2();//报错
}
强制在抽象类中使抽象方法达到同步的效果
abstract class TestAbstract {
public synchronized void m() {
print();
}
public abstract void print();
}
public class TASon extends TestAbstract {
@Override
public void print() {
System.out.print("aaaaaaaaaa");
System.out.print("bbbbb");
}
public void test() {
new Thread() {
@Override
public void run() {
while (true) {
m();
}
}
}.start();
new Thread() {
@Override
public void run() {
while (true) {
m();
}
}
}.start();
}
public static void main(String[] args) {
new TASon().test();
}
}
调用完m方法可以再去试试调用print方法,可以发现后者多a少b了的现象(忽略控制台的最前面和最后面那部分的结果,前面是缓冲区不够了挤掉了,后面是自己强制停止运行的结果)
本来想在test方法上加上@Test注解的,问题有二,一是若所在类不是public的话则启动不了Test,二是执行一会就停了(即使我使用了无限循环,未解决)