修饰符英文名 | 修饰符意译中文名 |
private | 私有的 |
public | 公有的 |
protected | 受保护的 |
修饰符英文名 | 修饰符意译中文名 |
final | 强制禁止覆盖 |
abstract | 强制覆盖 |
static | 静态的 |
synchronized | 重量级锁-同步的 |
volatile | 轻量级锁 |
extends | 继承 |
super | 超 |
class | 类 |
new | 实例 |
interface
|
声明接口 |
implements | 实现接口 |
strictfp | 精确浮点 |
transient |
不可序列化 |
native | 本地方法 |
关键字英文名 | 关键字意译中文名 |
if | 条件关键字 |
else | 条件关键字 |
for | 循环关键字 |
while | 循环关键字 |
do | 循环关键字 |
switch | 选择关键字 |
case | 选择关键字 |
break | 结束循环关键字 |
continue | 结束本次循环关键字 |
return | 方法返回关键字 |
default | 选择关键字 |
instanceof | 判断某一对象是否属于某一类 |
二.具体介绍(使用方法+代码实现)
1.访问控制修饰符
1)private--私有的
private关键字可声明方法,变量。不能标识类,其作用范围只能是当前类中,也就是说对于其他类,这些被标识的字段会被隐藏变成不可视。
class UesPrivate{
//声明一个私有的整型key变量
private int key;
//声明受保护的构造函数,其将造成不能实例化该类的对象
private void UsePrivate() {
}
}
//试图声明私有的接口 结果出现"Illegal modifier for the interface Pint; only public & abstract are permitted"编译错误
private interface Pint{
}
//试图声明私有的类 结果出现"Illegal modifier for the interface Pint; only public & abstract are permitted"编译错误
private class Example1{
}
2)public--公有的
public关键字可声明接口,类,方法,变量。被public关键字标识的字段,可以被其他类所调用,即使不在用一个java中,也可以被调用(但必须为与用一个java包)使用public关键字要注意一下几点
①.一个java文件只能有一个public关键字的顶级类
//尝试创建与文件名不同第二个带有public关键字的顶级类
//结果产生编译错误"The public type UsePublic must be defined in its own file"
public class UsePublic{
}
//带有public关键字的顶级类
public class keywordExample {
public static void main(String [] a) {
}
}
②.嵌套类可以使用public关键字
public class keywordExample {
//创建带有public关键字的成员类
public class UsePublic{
}
public static void main(String [] a) {
}
}
③.一个java文件不能有一个带有public关键字的接口
//尝试把带有public的接口创建在文件名顶级类的外部结果产生编译错误"The public type UsePublic must be defined in its own file"
public interface USP{
}
public class UseP{
//创建在顶级类内部的public接口
public interface UP{
}
}
④.带有public关键字的字段可以定义在类,接口的内部
class Example2{
//声明public的整型变量i
public int i;
//声明public构造函数
public void Example2() {
}
//声明public的类
public class Exp{
}
//声明public的接口
public interface Xp{
}
}
3)protected--受保护的
class UseProtected{
//声明一个受保护的整型key变量
protected int key;
//声明受保护的构造函数,其将造成只能使用子类实例化该对象
protected void UsePrivate() {
}
}
class ChildProtected extends UseProtected{
public void ChileProtected() {
//子类使用父类受保护的key变量
this.key = super.key;
//实例化父类的对象
UseProtected up = new UseProtected();
}
}
public class keywordExample {
public static void main(String [] a) {
//不是UseProtected的子类实例化其对象产生编译错误“UsePrivate cannot be resolved to a type”
UsePrivate uu = new UsePrivate();
}
}
2.类,方法,变量修饰符
1)final--强制禁止覆盖
final关键字可以用于类,方法,变量作为他们的修饰符,不能修饰接口。final关键字的作用正如其翻译“最终的”,不可改变的。其意思也就是说,被修饰的字段不能被改变。
①.final修饰类时
当final作用于类时,即告诉这个类禁止继承。禁止继承的类主要是出于两方面考虑其一是性能,其二是安全。比如说java.lang.Math和java.lang.String类都被fianl关键字所修饰。
//定义一个被final修饰的类UseFinal
public final class UseFinal{
public final void FinalExample() {
}
}
//尝试继承UseFinal类,产生编译错误“The type ChileFinal cannot subclass the final class keywordExample.UseFinal”
public class ChileFinal extends UseFinal{
}
②.final修饰方法时
当final修饰符作用于方法时,这个方法将不能被覆盖。对于在final修饰符作用的类内部的方法,无论定不定义都不将被覆盖。
//定义一个被final修饰的类UseFinal
public final class UseFinal{
//在final修饰的类内部的方法 其也是不能被覆盖的
public final void FinalExample() {
}
}
//在没有final修饰符修饰类内部定义带有final修饰的方法。
//即使类被继承,在子类也不能覆盖这个方法
final void FinalExample2() {
}
③.final修饰变量时
当final修饰符作用变量时,这个变量将会被定义成常数。意思就是说,在其生命周期内这个变量的值将不会被改变。并且声明常数时只能在方法内部进行声明。final修饰变量时,不用管类,方法是否使用final修饰另外当被final修饰的变量在方法外部,类内部时必须对其赋值。
final void FinalExample2() {
//定义常数K,一般变量名采用大写与一般变量进行区分
final int K;
}
public final class UseFinal{
//在类内部,方法外部必须对该常数值进行赋值
//否则出现"The blank final field KEY may not have been initialized"编译错误
final int KEY = 2;
public final void UseKey() {
}
}
2)abstract--强制覆盖
3.超类的对象本身没有实际意义
1.java.swt.Component是被abstarct修饰的类,其下面有许多的子类,都是一些关于控件的类比如说:滚动条类,对话框类,标签类。满足第一个条件
2.每个控件类都有许多的操作方法,但我们不需要知道是什么控件,就可以把这个控件加入到相应的容器中显示。满足第二个条件把所有的子类当做超类,加入到容器中显示。
3.对于Component类其没有具体的真实的对象,比如他的子类对话框类可以在容器上添加显示一个对话框,Component类没有具体这样的功能,因此这个超类本身是无意义的。
//父类没有具体的攻击招式
public abstract class AttackMonster{
public abstract void useArm();
public abstract void useLeg();
public void addAttack() {
}
}
//子类具有实际的攻击方法和怎么攻击的招式和对象
public class Man extends AttackMonster{
public void useArm() {
//使用手臂攻击..
}
public void useLeg() {
//使用腿攻击..
}
public void addAttack(AttackMonster a) {
//添加的相应的攻击招式 不必知道谁添加..
//但是可以产生相应的效果
}
}
//同上面 Woman具有实际意义的攻击
public class Woman extends AttackMonster{
public void useArm() {
}
public void useLeg() {
}
}
public class Attack{
//创建一个攻击方法可以获得能够使用相应攻击的子类,传递的是父类的类型
public AttackMonster useAttack(AttackMonster a) {
a.useArm();
a.useLeg();
a.addAttack();
return a;
}
}
public static void main(String [] a) {
Attack ak = new Attack();
Man m = new Man();
//把相应谁使用的攻击招式使用
ak.useAttack(m);
}
②.abstract修饰方法时:
public abstract class UseAbstract{
void UU() {
}
//在抽象类创建的抽象方法无编译错误
abstract void kk() ;
}
public class UseAbstract2{
//在公共类创建的抽象方法产生编译错误
//"The abstract method ll in type UseAbstract2 can only be defined by an abstract class"
abstract void ll() ;
}
3)static--静态的
static关键字可以修饰类,方法,变量,和代码块。被static关键修饰修饰的字段,不需要依赖于对象访问,可以直接通过类名访问(即没有this指针指向外部的字段)
①.static修饰类时:
当static修饰类,这个类必须是嵌套类。被声明成静态嵌套类,没有this指针指向外嵌类的实例字段,也就是说静态嵌套类不能访问其嵌套类对象中的实例数据。但可以声明他本身,或外部类的实例对象访问相应的实例数据。在静态嵌套类的静态变量必须是常量(也就是说这个静态变量必须是常量)
public class UseStatic{
//若嵌套类不是静态嵌套类时 使用静态方法会产生错误
//"The method xx cannot be declared static; static methods can only be declared in a static or top level type"
static void xx() {
}
}
//非内部嵌套类 静态方法可以直接使用不会产生编译错误,静态变量可以不是常量
class UseStatic2{
private static String sst = "222";
private String nsst = "222";
static void kk() {
}
}
②.static修饰方法时:
当static修饰方法时,不能在静态方法内部访问非静态方法(或变量)的字段(即必须实例化对象,通过实例对象访问,不能使用this指针指向非静态方法,此外不能实例化内部类只能实例化外部类)。而非静态方法可以直接访问静态方法(或变量)的字段(可直接通过类名进行访问)。
void UseNotStatic() {
UseStatic.UseStatic();
this.UseStatic();
String s = this.sst;
}
//静态方法必须通过对象的实例化访问相关的非静态方法
static void UseStatic() {
UseStatic us = new UseStatic();
us.UseNotStatic();
}
静态方法不需创建对象可直接使用,而动态方法需要创建对象(占用相应的内存空间),才能调用相应的动态方法
静态方法不能放在嵌套类中,只能放在顶级类中,比如带有文件名的类中
③.static修饰变量时:
当static修饰变量,意思这个变量被所有的对象所拥有,在内存只存在一个副本(意思是只有一个),而非静态变量只有特定相应的对象拥有,在内存中存在多个副本。
public static class UseStatic{
private static final String sst = "222";
private String nsst = "222";
//非静态方法通过类名或this关键字访问非静态方法的字段
void UseNotStatic() {
UseStatic.UseStatic();
this.UseStatic();
//sst变量被所有的对象所拥有,故可以使用this关键字访问该对象
String s = this.sst;
//nsst只能被UseStatic类对象用于,因为该方法时非静态方法故也可以直接访问
String s2 = this.nsst;
}
//静态方法必须通过对象的实例化访问相关的非静态方法
static void UseStatic() {
UseStatic us = new UseStatic();
us.UseNotStatic();
String s = us.nsst;
String s2 = us.sst;
//静态方法想访问相应的字段,必须只能实例化对象,通过对象访问
}
}
④.static关键字修饰代码块时
当static关键字修饰代码块时,意思是这个代码只能在程序执行期间只执行一次。static代码块可以存在于类中的任何地方
static {
//在程序中执行一次的类
class Uu{
//.....
}
}
4)synchronized-同步的
synchronized关键字可以修饰类方法,实例方法或代码块。该关键字用作线程同步的代码块中,一个线程在该代码块执行时必须获取“指定对象的互斥锁”,才能执行相应的代码块。当互斥锁被另一个线程占有,则申请锁的线程将会被挂起(其他的线程会被放在阻塞队列中),直至锁被释放
①.synchroinzed用作类方法
类方法是这个类的静态方法,是这个类的成员。当synchronized关键字修饰类方法时,等于把这个类方法代码块同步执行,不管运行时存在多少对象,在类方法中只能存在一个获得类对象锁的线程运行(注意与下面实例方法做区别)
同步执行的类方法
public void run() {
//线程的生命周期
staticprint();
//this.print();
}
//定义成类方法的同步代码块
public static synchronized void staticprint() {
for(int k = 0;k<3;k++) {
//输出当前线程使用的k值
try {
System.out.println(Thread.currentThread().getName()+" 使用:k = "+k);
Thread.sleep(1000);
}catch(Exception e) {
System.out.println("线程出问题");
e.printStackTrace();
}
}
}
public static void main(String [] a) {
UseSY us = new UseSY();
UseSY us2 = new UseSY();
Thread [] t1 = new Thread[10];
Thread t2 = new Thread(us2);
for(Thread temp : t1) {
//创建10个线程执行
temp = new Thread(us);
temp.start();
}
}
运行上述程序将产生一下结果
很明显这些线程都是同步执行的.
这是未同步执行的代码
//未互斥执行的代码块
public void otherprint() {
for(int j = 0;j<3;j++) {
try {
System.out.println(Thread.currentThread().getName()+" 使用:j = "+j);
Thread.sleep(1000);
}catch(Exception e) {
System.out.println("线程出问题");
e.printStackTrace();
}
}
}
产生的相应输出
很明显这结果并不是同步执行的。
②.synchronized用作代码块时
由于,使用synchronized关键字修饰的代码块,需获得相应的对象锁,而使用synchronized的代码这可以显示指定线程必须获得某个对象的对象锁后,执行之后的代码块。
//同步的代码块,指定对象是当前对象
synchronized(this){
//无同步的方法
this.otherprint();
}
产生的输出结果,很明显是同步的
③.synchornized用做实例方法时
当把一个实例方法定义成一个互斥的方法时,提供的对象锁是隐式的,也就是说每个线程都将获取相应的对象锁,此时将不会产生线程互斥的情况
public synchronized void print()
//此时该代码等价于
public void print(){
synchroinized(this){
//....
}
}
因为每个线程都会创建一个"this"对象,所以每个线程都会获得“this”对象的对象锁,此时将不会产生线程互斥的效果比如说:
public synchronized void print() {
for(int i = 0;i<3;i++) {
try {
System.out.println(Thread.currentThread().getName()+" 使用:i = "+i);
Thread.sleep(1000);
}catch(Exception e) {
System.out.println("线程出问题");
e.printStackTrace();
}
}
}
public static void main(String [] a) {
UseSY us = new UseSY();
UseSY us2 = new UseSY();
Thread [] t1 = new Thread[10];
Thread t2 = new Thread(us2);
t1[0] = new Thread(us);
t1[0].start();
t2.start();
//上述代码将会在程序中存在于两个线程
}
很明显两个线程都不访问变量i字段,此时synchronized关键字无作用
总结一下:
1.synchronized作用于类方法时,获取的是类的对象锁,即使运行时存在多个线程,这个线程也只会互斥的运行
2.synchronized作用于代码块时,获取的是指定对象的对象锁
3.synchronized作用于实例方法时,获取的是"this"对象的对象锁,此时运行时存在多个线程将不会产生线程互斥的效果
5)volatile--轻量级锁
voilatile关键字相比于synchronized关键字是一种轻量级锁,它支持同步机制中的内存可见性。但不具备原子性的操作,比如说复杂的读,加减,写操作。它相比于synchronized关键字更具备性能优势性,因为它不会造成线程阻塞。
volatile关键字用做变量。
public class KeyWordExample4_Volatie extends Thread{
/**
* volatile关键字可以对共享变量的内存可见性进行及时的更新
* 比如说,一个线程更改了某个变量的值,对于另一个变量是不可见的
* 若使用了volatile关键字则对于另一个变量是可见。线程并发性执行时另一个议题
*/
static volatile int a = 0;
public static void main(String [] s){
for(int i = 0;i<5 ;i++) {
new Thread(new Runnable() {
public void run() {
a++;
}
}).start();
}
System.out.println(a);
}
}
比如上面这个例子中,它的输出结果可能是0,1,2,3,4等,这是为什么?
因为对于并发性的线程,当线程A修改了a的值,线程B也同时修改了a的值,并且同时写到主内存中共享变量的内存地址中,这将造成两个线程同时为这个变量更新了值。
所以,想要使用volatile变量提供线程安全需要求两个条件
1.对变量的写操作不依赖当前的值
2.该变量没有包含在其他变量的不变式中
6)extends--继承
继承概念和现实生活中继承概念相同,同样都是继承父辈的一些东西。在java中子将继承父辈的变量,方法。并且在这基础上添加自己的方法,变量等
java中把继承树的根节点称为父类或超类,子节点称为子类.
java不支持多重继承,即子类不允许有多个父类,但父类允许有多个父类
class Class{
/**
* 父类设置一些方法,子类可以获得这些方法,并且进行输出
*/
private String grade;
private String num;
private String name;
public String getName(String name) {
this.name = name;
return name;
}
public String getNum(String num) {
this.num = num;
return num;
}
public String getGrade(String grade) {
this.grade = grade;
return grade;
}
}
class Student extends Class{
//子类设置一些父类没有的方法
public String getFarther(String farther) {
this.farther = farther;
return farther;
}
}
public class KeyWordExample5_Extends {
public static void main(String [] a) {
Student sd = new Student();
System.out.println(sd.getName(“222”)+sd.getNum("222")+sd.getGrade("1")+sd.getFarther("fff"));
}
上述程序结果将是“2222221fff”。
①. java中重写父类的方法,称为覆盖。在运行时调用谁的方法,主要看是什么对象,若是父类对象则调用父类的方法,若是子类的对象则调用子类的方法。
class Class{
/**
* 父类设置一些方法,子类可以获得这些方法,并且进行输出
*/
private String grade;
private String num;
protected String name;
public String getName(String name) {
this.name = name;
return name;
}
public String getNum(String num) {
this.num = num;
return num;
}
public String getGrade(String grade) {
this.grade = grade;
return grade;
}
}
class Student extends Class{
//子类设置一些父类没有的方法
private String farther;
public String getFarther(String farther) {
this.farther = farther;
return farther;
}
public String getName() {
this.name = super.getName("sss");
return name;
}
}
public class KeyWordExample5_Extends {
public static void main(String [] a) {
Student sd = new Student();
System.out.println(sd.getName()+sd.getNum("222")+sd.getGrade("1")+sd.getFarther("fff"));
}
上述程序运行结果是“sss2221fff”
②.java中继承中,构造函数时层次调用的,比如说在运行中会先执行父类的构造函数,在按照继承树依次执行子类的构造函数。
class Farther{
Farther(){
System.out.println("这是父类");
}
}
class Child1 extends Farther{
Child1(){
System.out.println("这是Farther的子类");
}
}
class Child2 extends Child1{
Child2(){
System.out.println("这是Child1的子类");
}
}
public class KeyWordExample5_Extends {
public static void main(String [] a) {
Child2 ch = new Child2();
这个程序将会依次打印“这是父类,这是Farther的子类,这是Child1的子类”。
若对于有参数的构造函数,此时必须要写出子类的构造函数,并且给父类的构造函数,传递实参。
class Farther{
Farther(String s){
System.out.println(s);
}
}
class Child1 extends Farther{
Child1(String s){
super("这是父类");
System.out.println(s);
}
}
class Child2 extends Child1{
Child2(){
super("这是Farther的子类");
System.out.println("这是Child1的子类");
}
}
这个程序也会依次打印“这是父类,这是Farther的子类,这是Child1的子类”。
③.强制类型转换
在继承树中,可以执行向上或向下的类型转换,但不允许执行同结点的类型转换
1)可以执行父类 = 子类赋值。因为子类是属于父类的。另外,可以执行跨级层次的赋值,即父类是子类更远的父类。
2)可以执行子类 = 子类(父类)强制类型转换赋值。在运行时将进行检查。如果父类时正确的子类型,赋值将正常执行。若不是,则将出现异常
3)不允许不想关的类之间进行赋值转换。
7)super--超
super关键字一般用子类中,使用super关键字可以访问该类父类的字段(比如变量,方法)。若由于子类覆盖父类的方法,也可以使用super关键字调用父类的方法。
①.使用父类的变量
//声明一些父类的字段供子类调用
protected int count = 0;
public String somethings = "this is farther";
public void getContent() {
childcount = super.count;//使用父类的count变量
childstring = super.somethings;//使用父类的somethings变量
System.out.println(childcount+childstring);//输出
}
②.使用父类的方法
//父类的公共方法
public void setSomethings() {
count = 1;
}
public void getContent() {
super.setSomethings();
childcount = super.count;
childstring = super.somethings;
System.out.println(childcount+childstring);
}
public class KeyWordExample6_Super {
public static void main(String [] a) {
Child ch = new Child();
ch.getContent();
}
}
上面讲输出结果“1this is farther”
③.调用父类的构造函数
调用父类的构造函数,通常使用关键字super(),并且一般在子类的构造函数中使用。
使用情况有两种:
1.父类初始化相关语句子类需要
2.父类带有参数传递时,子类需要使用super()方法。(因为在实例化子类对象时,先调用父类构造函数,然后依次向下层次调用)
class NewFarther{
//声明一些父类的字段供子类调用
protected static int count = 0;
public static String somethings = "this is farther";
//父类的公共方法
public void setSomethings() {
count = 1;
}
//父类带有String类的形参,实例化子类时,通过子类构造函数向父类传递参数
protected NewFarther(String s) {
somethings = s;
}
public NewFarther getFarther() {
return this;
}
}
class Child extends NewFarther{
//设置一些子类私有字段,这些字段的内容是从父类得到的
private int childcount ;
private String childstring;
public Child(){
super("这是子类提供的");
}
public void getContent() {
super.setSomethings();
childcount = super.count;
childstring = super.somethings;
System.out.println(childcount+childstring);
}
}
public class KeyWordExample6_Super {
public static void main(String [] a) {
Child ch = new Child();
ch.getContent();
}
}
上述语句将产生输出“1这是子类提供的”。
8)class--类
java通过class关键字声明一个“类”。这个类里面包含了变量/方法字段的集合。类似于C中的“结构体”,但却不同它,后者主要包含一些声明变量字段。类是一种数据类型的别名,即它是一种引用类型。
①.使用class关键字
//使用class关键字声明了一个类
public class UseKeyWords{
//在这个类中声明一些成员,比如整型,字符串,方法等的
private int count;
private String string;
public void UseKey() {
count = 1;
}
}
② public class 与 class的区别
1.在一个*.java文件中,类树的顶点只能存在一个与文件名一致的public class * 或 class *均可以
2.当使用class声明与文件名不同名时,必须执行它生成的*.class文件
3.main()函数必须放在public class 或者 class定义的顶级类中
class KeyWordExample7_Class {
public static void main(String [] a) {
System.out.println(System.getProperty("user.dir"));
}
比如这个语句将打印“D:\java文件\总结”
class KeyWordExample7 {
public static void main(String [] a) {
System.out.println(System.getProperty("user.dir"));
}
或者定义与文件名不同的类名,执行它生成的KeyWordExample7.class文件,同样可以得出上面的结果
class KeyWordExample7 {
//使用class关键字声明了一个类
public class UseKeyWords{
//在这个类中声明一些成员,比如整型,字符串,方法等的
private int count;
private String string;
public void UseKey() {
count = 1;
}
}
public static void main(String [] a) {
}
}
9).new--实例
使用new关键字是创建一个新对象的唯一方法(除了克隆)。java对象是类变量。
创建对象,需要3步,声明引用变量,实例化,初始化
①.声明引用变量
所有的对象都是通过引用(即指针)访问,声明一个对象变量实际上只是得到一个能够存储对象引用(指针)的变量。
所以,声明一个对象变量,我们实际得到一个并不指向任何对象的null指针。
②.实例化
通过关键字new实例化对象,实例化对象将做什么工作?
1.通过JVM计算对象中将拥有多少数据字段并为对象分配内存。
2.内存中所有的已知数据字段均设置为0、null等,因此,所有对象一开始就会处于一个已知的状态
③.初始化
1.初始化的第一步是调用构造函数,并且总是显式的或隐式的调用父类的构造函数,并且一直递归调用完所有已知该类父类的构造函数。
2.对带有显式初始化程序的任何数据字段执行初始赋值
3.执行任何存在的初始化程序(在构造函数里)。
4.执行对象构造函数中其他的语句
总结:获得对象,我们实际上获得的是对这个对象的引用(指针)变量标识符。我们可以通过这个标识符使用对象中任何存在的字段。
10).interface--声明接口
使用interface关键字可以声明一个接口,接口和类很相似,都是引用类型。接口和类不同的是可以继承多个接口,而类只能继承一个。接口的内部字段的属性总是具有:
1.接口中的成员(包括字段和方法)总是具有public属性,即使没有定义也如此,如果你想定义比如说private则会造成编译错误。
2.接口中的方法,总是具有abstract属性,即使没有定义也是如何。这也就是说,你只能写一个抽象方法,等实现它的子类覆盖它。
3.接口中的数据字段(比如说变量),总是具有final属性,即使没有定义也是如此。这也就是说,你不能修改接口的的数据字段。
另外,接口的签名,可以具有访问控制符,比如说,它可以是一个公共接口,私有接口,必须继承才能使用的接口等等。
//定义一个受保护的接口 [访问控制符 interface 接口名 ]<-是它的签名 和类的声明和相似
protected interface ThisInterface{
//接口里的方法总是具有 public abstract的属性
public abstract void a();
//接口里的数据字段总是具有 public final的属性
public final int i = 0;
}
再次说明一点的是,接口是引用类型,所以可以声明实例化它。并且它可以作为一种类型作为传递。比如说泛型等等。
11).implements--实现接口
implements关键字可以继承创建的接口,当然是类继承,和extends关键字的使用很相似,但implements关键字继承的是接口。并且java允许继承多个接口。
当时用接口的类型做形参时,可以使用该接口的类型或者实现它类的类型都可以
public interface ThisInterface{
//接口里的方法总是具有 public abstract的属性
public abstract void a();
//接口里的数据字段总是具有 public final的属性
public final int i = 0;
}
//声明的第二个接口
public interface ThisInterface2{
public abstract void b(ThisInterface b);
public final int j = 0;
}
//implements关键字的使用 [.. 类名 implements 接口1,接口2,...,接口n ]<-其中两个接口用","隔开
public class Tht implements ThisInterface,ThisInterface2{
//接口的抽象方法在其继承的子类中覆盖.
@Override
public void a() {
// TODO Auto-generated method stub
}
//当调用这个方法时,可以是使用接口"ThisInterface"或实现这个接口类的类型的参数,都是允许的
//这和父子类 和它的父子类型具有相同的道理
@Override
public void b(ThisInterface b) {
// TODO Auto-generated method stub
}
}
12)strictfp--精确浮点
strictfp即 strict float point (精确浮点),使用strictfp关键字修饰的字段,都将严格按照 IEEE 754中的约定,所有的字段的结果,都必须是单精度或者双精度表示。strictfp关键字可以修饰类,接口,方法,变量。
①修饰类或接口时
当strictfp修饰类或者接口的时候,该类的所有代码的表达式运算结果都将以单精度或双精度表示出来
②修饰方法时
该方法内部的所有字段也是严格按照IEEE-754约定的精度值进行转换
③修饰变量时
同理,变量字段的值也只能按照IEEE-754约定的精度转换
总结:什么是必须按照IEEE-754规定严格进行转换,因为每个浮点数处理器的运算能力各不相同,为了避免这种差异性,所以java使用strictfp使用IEEE-754规定的进行浮点数转换,达到每台计算机的结果都能够统一
13)transient--不可序列化(串行化)
首先谈谈什么是序列化,序列化特指对象序列化。java对象序列化将对象的所有字段(比说,对象存储的数据和信息)字节化存储在磁盘上。可以存放在数据库中,也可经网络传输到另一台计算机中。当我们再次需要的时候可以反序列化,把对象的字节信息转换为原来对象的所有字段。对象序列化需要实现Serializable接口
使用transient关键字修饰的字段,则表示它不能把相关的字段进行序列化。这可以为我们把我们不想实现序列化的对象提供了方便,并且节省内存空间
14)native--本地方法
使用native关键字只能标记方法,它有点像使用abstract关键字,只能声明一个抽象的方法。但其本质是调用C/C++的函数。也就是说使用native关键字的方法,将会调用相应的C/C++函数。这是怎么实现的?介绍一下java native interface--JNI java本地接口。JNI主要任务就是调用C/C++的函数动态链接库。
首先java编译完成后生成.class文件后,jvm发现其需要调用C/C++的函数。此时同过JNI找到相应的C/C++生成的动态链接库,然后载入库的内容,从而完成调用的过程。
2.程序控制关键字
1)if--条件控制关键字
if关键字代表了一种类型的语句,即选择语句。if语句的一般语法如下
// if (Expression) Statement
其中Expression为判断的表达式,其值只能是boolean类型的。比如:
// if(true) if(false)
但也允许判断某变量是否大于等于小于等三种方式,比如:
// if(x>10) if(x<10) if(x==10)
也可以判断两变量值是否相等,或者其他的某种关系,比如:
// if(x==y) if(x instanceof y)
其中Statement部分可以只是一条语句也可是代码块,比如:
// if(true) x = y; if(x<10){x = y; x = x + 5;}
2)else--条件控制关键字