1. abstract(抽象)
用法:类修饰符的一种,可以用来修饰类,方法,被修饰的类不能够实例化(即不能用new关键字得到对象),被修饰的方法不能够实现。一个抽象类中不一定要有抽象方法,但是一个类里面有抽象方法就一定是抽象类。如果由类要继承抽象类的话,必须要实现里面的抽象方法。构造方法和静态方法不可以修饰为抽象。
例子:
public abstract class Animal {
public abstract void cry();
public void run(){
System.out.println(“跑的方法……”);
}
}
abstract关键字可以修改类或方法。
abstract类可以扩展(增加子类),但不能直接实例化。
abstract方法不在声明它的类中实现,但必须在某个子类中重写
-示例-
public abstract class MyClass{}
public abstract StringmyMethod();
采用abstract方法的类本来就是抽象类,并且必须声明为abstract。abstract类不能实例化。
仅当abstract类的子类实现其超类的所有abstract方法时,才能实例化abstract类的子类。这种类称为具体类,以区别于abstract类 。
final 类的方法都不能是 abstract,因为 final 类不能有子类。
< 1> abstract抽象用在类的声明中来指明一个类是不能被实例化的,但是可以被其他类继承。一个抽象类可以使用抽象方法,抽象方法不需要实现,但是需要在子类中被实现。它的用途是向子类提供通用的信息。抽象类可以包含正常的类包含的任何东西,也就是说,类和实例变量,以及带有任何修饰词的方法。只有抽象类可能有抽象方法。如果一个不是抽象的类包含一个抽象方法,那么将会出现编译错误。
例子:如果下列的一个成立,那么一个有抽象方法:
a.它显式的声明了一个abstract方法。
b.它从它的直接父类继承了一个抽象方法。
c.一个直接的类的父借口声明或继承了它的一个方法(这因此必须是abstract)
<2>如果用户声明private,static,和final方法为abstarct,编译错误将出现。
不可能重设一个private方法,因为一个abstarct private永远不能被实现。
static方法总是可用的,因此必须有一个实现;static abstract将永远没有实现。
final方法不能被重设,因此不回有final abstract方法的实现。
2.extends 解释:扩充,扩展
用法:一个类继承另一个类的关键字,当出现了这个关键字,两个类就有了继承关系,extends前面的类,我们称之为父类。
extends后面的类,我们称之为子类。有了继承关系之后,我们就说子类拥有父类继承下来的所有非私有的成员(包括了属性,方法),但是不包括构造方法 。
extends 关键字用在 class 或 interface 声明中,用于指示所声明的类或接口是其名称后跟有 extends 关键字的类或接口的子类。
-示例-
public class Rectangle extends Polygon{ }
-注释-
在上例中,Rectangle 类继承 Polygon 类的所有 public 和 protected 变量和方法。
Rectangle 类可以重写 Polygon 类的任何非 final 方法。 一个类只能扩展一个其他类。
3.final
解释:最终的,决定性的
用法:修饰符的一种,它可以用来修饰类,方法,属性。当一个属性被修饰成final的之后,这个属性变成了常量,它的值必须在定义的时候初始化,并且后面的代码不能对其进行修改,它的命名应该全部都是大写。当一个方法被修饰成final的之后,这个方法在继承中是不能够被进行覆盖的。当一个类被修饰成final的之后,这个类不能再有子类。
final 关键字可以应用于类,以指示不能扩展该类(不能有子类)。 final 关键字可以应用于方法,以指示不能重写任何子类中的方法。
-示例-
public final class MyFinalClass{ }
public class MyClass{
public final String myFinalMethod() {
<statements> } }
例子:
public final class Math{ private final float PI = 3.1415926;
public final int abs(int i){ return i>=0?i:-I;
} } -注释-
一个类不能同时是 abstract 又是 final。abstract 意味着必须扩展类,final 意味着不能扩展类。
一个方法不能同时是 abstract 又是 final。abstract 意味着必须重写方法,final 意味着不能重写方法。
<1>对于基本类型前加以final修饰,表示被修饰的变量为常数,不可以修改。一个既是static又是final的字段表示只占据一段不能改变的存储空间。
<2>final用于对象应用时,final使应用恒定不变。一旦引用被初始化指向一个对象,就无法再把它指向另一个对象。
<3>final方法:一是把方法锁定,以防止继承类修改它的含义,二是确保继承中使方法行为保持不变,并且不会被覆盖。类中所有的private方法都隐式地指定为是final。
<4>final参数:对于基本类型的变量,这样做并没有什么实际意义,因为基本类型的变量在调用方法时是传值,也就是说你可以在方法中更改这个参数变量而不会影响到调用语句,然而对于对象变量,却显得很实用,以为对象变量在传递时是传递其引用,这样你在方法中对对象变量的修改也会影响到调用语句的对象变量,当你在方法中不需要改变作为参数的变量时,明确使用final进行声明,会防止你无意的修改而影响到调用方法。
<5>final类:当将某个类的整体定义为final时,就表明了该类不允许被继承。
3.finally
解释:最后,终于,不可更改地
用法:在异常处理机制当中,它的作用就像是人吃饭一样,必须得做的,不论有异常还是没有异常都要执行的代码就可以放到finally块当中去。finally块,必须要配合try块一起使用,不能单独使用,也不能直接和catch块一起使用。
finally 关键字用来定义始终在 try-catch-finally 语句中执行的块。finally 块通常包含清理代码,用在部分执行 try 块后恢复正常运行。
-示例- try{
<可能引发异常的块> }
catch (<java.lang.Exception 或子类> e){
<处理异常 e 的代码>
} finally{
<有异常或无异常情况下都执行的语句> } -注释-
开始和结束标记 { 和 } 是 finally 子句语法的一部分,即使该子句只包含一个语句,也不能省略这两个标记。
每个 try 块都必须至少有一个 catch 或 finally 子句。
如果执行 try 块的任何部分,不论是否出现异常,也不论 try 或 catch 块是否包含 return、continue 或 break 语句,都一定会执行 finally 块中的代码。 如果不出现异常,控件将跳过 try 块,进入 finally 块。 如果在执行 try 块期间出现异常,并且相应的 catch 块包含 break、continue 或 return 语句,控件将首先穿过 finally 块,之后再执行 break、continue 或 return。
5、implements(接口)
用法:用来让一个类实现一个接口的关键字,实现接口的这个类必须实现接口里面所有的方法。
implements 关键字在 class 声明中使用,以指示所声明的类提供了在 implements 关键字后面的名称所指定的接口中所声明的所有方法的实现。
-示例-
public class Truck implements IVehicle{ } -注释-
在上例中,Truck 类必须提供在 IVehicle 接口中所声明的所有方法的实现。
否则,Truck 类将是独立的;它可以声明其他方法和变量,并扩展另一个类。 一个类可以实现多个接口。
finally
解释:
最后,终于,不可更改地
用法:
在异常处理机制当中,它的作用就像是人吃饭一样,必须得做的,不论有
异常还是没有异常都要执行的代码就可以放到
finally
块当中去。
finally
块,
必须要配合
try
块一起使用,
不能单独使用,也不能直接和
catch
块一起使用。
finally
关键字用来定义始终在
try-catch-finally
语句中执行的块。
finally
块通常包含清理代码,用在部分执行
try
块后恢复正常运行。
-
示例
-
try{
<
可能引发异常的块
>
}
catch (<java.lang.Exception
或子类
> e){
<
处理异常
e
的代码
>
6、instanceof
用法:instanceof 关键字用来确定对象所属的类。
-示例-
if (node instanceof TreeNode){ <statements> } -注释-
在上例中,如果 node 是 TreeNode 类的实例,或者是 TreeNode 的子类的实例,则 instanceof 表达式的值将为 true。
instanceof 通常是用于判断父类或者接口的引用是否是某个子类的实例,例如:
class Animal{}
class Bird extends Animal {} class Dog extends Animal {} Animal a= new Bird();
System.out.println( a instanceof Bird); System.out.println( a instanceof Dog);
7、interface
解释:接口,界面
用法:它本质上是一个类,一个完全抽象的类,里面没有任何实现的方法。它不是用来继承的,是用来实现的。某个类如果实现了接口就必须要实现接口里面的所有方法。并且接口是不能用来实例化的,它也是不能通过new关键字获得对象。
interface 关键字用来声明新的 Java 接口,接口是方法的集合。 接口是 Java 语言的一项强大功能。任何类都可声明它实现一个或多个接口,这意味着它实现了在这些接口中所定义的所有方法。
-示例-
public interface IPolygon{
public float getArea(); public int getNumberOfSides(); public int getCircumference(); } -注释-
实现了接口的任何类都必须提供在该接口中的所有方法的实现。 一个类可以实现多个接口。
8、static 解释:静态的
用法:修饰符的一种,能够用来修饰属性和方法。需要注意的是被修饰的属性和方法,不再属于对象所有,而是属于类,意味着,要访问这些属性和方法不再通过对象而是直接用类名来访问。另外,静态的方法不能够访问非静态属性,非静态的方法能够访问静态的属性。
static 关键字可以应用于内部类(在另一个类中定义的类)、方法或字段(类的成员变量)。
-示例-
public class MyPublicClass{ public final static int MAX_OBJECTS = 100; static int _numObjects = 0; static class MyStaticClass{ }
static int getNumObjects(){ } } -注释-
通常,static 关键字意味着应用它的实体在声明该实体的类的任何特定实例外部可用。
static(内部)类可以被其他类实例化和引用(即使它是顶级类)。在上面的-示例-中,另一个类中的代码可以实例化 MyStaticClass 类,方法是用包含它的类名来限定其名称,如 MyClass.MyStaticClass。
static 字段(类的成员变量)在类的所有实例中只存在一次。可以从类的外部调用 static 方法,而不用首先实例化该类。这样的引用始终包括类名作为方法调用的限定符。在上面的示例中,MyClass 类外部的代码以 MyClass.getNumObjects() 的形式调用 getNumObjects() static 方法。
模式:
public final static <type> varName = <value>;
通常用于声明可以在类的外部使用的类常量。在引用这样的类常量时需要用类名加以限定。在上面的-示例-中,另一个类可以用 MyClass.MAX_OBJECTS 形式来引用 MAX_OBJECTS 常量。
1>通常在一个类中定义一个方法为static,就是说无须本类的对象就可以直接调用。
2>静态变量和静态方法类似。所有此类实例共享此静态变量,也就是说类装载时,只分配一块存储空间,所有此类的对象都可以操控此块存储空间,当然对于final就另当别论了。
3>static定义的变量会优先于任何其他非static变量,不论其出现顺序如何。
4>static{}着是用来显式的静态变量初始化,这段代码只会初始化一次,且在类被第一次装载时。
5>在涉及到继承的时候,会先初始化父类的static变量,然后是子类的。
6>通常一个普通类不允许声明为静态的,只有一个内部类才可以。这时这个声明为静态的内部类可以直接作为一个普通类来使用,而不需要实例一个外部类。
9、synchronized
用法:synchronized 关键字可以应用于方法或语句块,并为一次只应由一个线程执行的关键代码段提供保护。当它用来修饰一个方法或者一个代码块的时候,能够保证在同
一时刻最多只有一个线程执行该段代码
-示例-
public class MyClass{
public synchronized static String mySyncStaticMethod(){ }
public synchronized String mySyncMethod(){ } }
public class MyOtherClass{
Object someObj;
public String myMethod(){
<statements>
synchronized (someObj){
<statements affecting someObj> }}}
synchronized 关键字可防止代码的关键代码段一次被多个线程执行。 如果应用于静态方法(如上例中的 MySyncStaticMethod),那么,当该方法一次由一个线程执行时,整个类将被锁定。
如果应用于实例方法(如上例中的 MySyncMethod),那么,当该方法一次由一个线程访问时,该实例将被锁定。
如果应用于对象或数组,当关联的代码块一次由一个线程执行时,对象或数组将被锁定。
synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。
1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。
如: public synchronized void accessVal(int newVal);
synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。
synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变
量的代码放到专门的方法中,
将其声明为
synchronized
,
并在主方法中调用来
解决这一问题,
但是
Java
为我们提供了更好的解决办法,
那就是
synchronized
块。
2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下:
synchronized(syncObject) { //允许访问控制的代码 }
synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。
对synchronized(this)的一些理解
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。package ths;
public class Thread1 implements Runnable { public void run() { synchronized(this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
} } }
public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread ta = new Thread(t1, "A");
Thread tb = new Thread(t1, "B");ta.start();
tb.start(); } }
二、当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
三、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
10、transient
用法:transient 关键字可以应用于类的成员变量,以便指出该成员变量不应 在包含它的类实例已序列化时被序列化。
-示例-
public class MyClass{
private transient String password; }
java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想
用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
11、volatile
用法:volatile 关键字用于表示可以被多个线程异步修改的成员变量。
注意:volatile 关键字在许多 Java 虚拟机中都没有实现。 -示例-
public class MyClass{
volatile int sharedValue; } -注释-
volatile 的目标用途是为了确保所有线程所看到的指定变量的值都是相同的。
Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到主内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
finally
解释:
最后,终于,不可更改地
用法:
在异常处理机制当中,它的作用就像是人吃饭一样,必须得做的,不论有
异常还是没有异常都要执行的代码就可以放到
finally
块当中去。
finally
块,
必须要配合
try
块一起使用,
不能单独使用,也不能直接和
catch
块一起使用。
finally
关键字用来定义始终在
try-catch-finally
语句中执行的块。
finally
块通常包含清理代码,用在部分执行
try
块后恢复正常运行。
-
示例
-
try{
<
可能引发异常的块
>
}
catch (<java.lang.Exception
或子类
> e){
<
处理异常
e
的代码
>
finally
解释:
最后,终于,不可更改地
用法:
在异常处理机制当中,它的作用就像是人吃饭一样,必须得做的,不论有
异常还是没有异常都要执行的代码就可以放到
finally
块当中去。
finally
块,
必须要配合
try
块一起使用,
不能单独使用,也不能直接和
catch
块一起使用。
finally
关键字用来定义始终在
try-catch-finally
语句中执行的块。
finally
块通常包含清理代码,用在部分执行
try
块后恢复正常运行。
-
示例
-
try{
<
可能引发异常的块
>
}
catch (<java.lang.Exception
或子类
> e){
<
处理异常
e
的代码
>