1.JAVA的关键字
java中的关键字有如下表格中这么多
表中null true false严格来讲不是关键字
常见的如下只做简单介绍
void 修饰方法没有返回值
基本数据类型 boolean int char short long double float byte
import 引入指定的 类或包 package 包
super父类引用或父类构造方法 this当前实例对象引用
goto / const 保留关键字 无意义
true false null 对/错/空
if else 判断 do while /for 循环
switch case default 分支
try catch 捕获异常
throw throws 抛出异常(一个/方法体定义声明可能会出现的异常)
private /protected /public 访问控制方式、私有/保护/公共
abstract /final /static 类和方法的修饰符 抽象的/最终的(不可被继承)/静态的
class interface 类和接口的关键字
extends 继承(单个) implements 实现接口(多个)
new 创建实例对象
instanceof 实例对象校验是否为指定类型
synchronized 多线程同步(代码块同步执行)
volatile 变量同步/发生变化
break 跳出一个循环或方法 continue 继续,回到某个地方
return 返回
不常见的如下做详细介绍加深印象
native 修饰方法的 —本地的 ,用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的
Java平台有个用户和本地C代码进行互操作的API,称为Java Native Interface (Java本地接口)。
Java Native Interface (JNI)标准就成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。
JNI一开始是为了本地已编译语言,尤其是C和C++而设计 的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
使用java与本地已编译的代码交互,通常会丧失平台可移植性。
但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。
JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下
步骤如下:
①、编写带有 native 声明的方法的java类,生成.java文件;(注意这里出现了 native 声明的方法关键字)
②、使用 javac 命令编译所编写的java类,生成.class文件;
③、使用 javah -jni java类名 生成扩展名为 h 的头文件,也即生成.h文件;
④、使用C/C++(或者其他编程想语言)实现本地方法,创建.h文件的实现,也就是创建.cpp文件实现.h文件中的方法;
⑤、将C/C++编写的文件生成动态连接库,生成dll文件;
strictfp 用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范
strictfp 关键字可应用于类、接口或方法
使用 strictfp 关键字声明一个方法时,该方法中所有的float和double表达式都严格遵守FP-strict的限制,符合IEEE-754规范。
当对一个类或接口使用 strictfp 关键字时,该类中的所有代码,包括嵌套类型中的初始设定值和代码,都将严格地进行计算。
严格约束意味着所有表达式的结果都必须是 IEEE 754 算法对操作数预期的结果,以单精度和双精度格式表示。
transient 声明不用序列化的成员域
序列化时被transient修饰的变量,是不会被序列化和反序列化的
例如读取某个类的实例对象时 读取字节序列反序列化为一个对象时被transient修饰的变量不会执行该操作
序列化:
序列化是指把一个Java对象变成二进制内容,本质上就是一个byte[]数组。 为什么要把Java对象序列化呢?因为序列化后可以把byte[]保存到文件中,或者把byte[]通过网络传输到远程,这样,就相当于把Java对象存储到文件或者通过网络传输出去了。 有序列化,就有反序列化,即把一个二进制内容(也就是byte[]数组)变回Java对象。有了反序列化,保存到文件中的byte[]数组又可以“变回”Java对象,或者从网络上读取byte[]并把它“变回”Java对象,来实现功能
①java.io.ObjectInputStream:对象输入流。
该类的readObject()方法从输入流中读取字节序列,然后将字节序列反序列化为一个对象并返回。
②java.io.ObjectOutputStream:对象输出流。
该类的writeObject(Object obj)方法将将传入的obj对象进行序列化,把得到的字节序列写入到目标输出流中进行输出。
只有实现了Serializable或者Externalizable接口的类的对象才能被序列化为字节序列(下为仅实现了Serializable接口的序列化和反序列化操作)
ObjectOutputStream采用默认的序列化方式,对对象的非transient的实例变量进行序列化。
ObjcetInputStream采用默认的反序列化方式,对对象的非transient的实例变量进行反序列化。
①序列化时,只对对象的状态进行保存,而不管对象的方法;
②当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
③当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
④并非所有的对象都可以序列化,至于为什么不可以,有很多原因了,比如:
安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行RMI传输等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的;
资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分配,而且,也是没有必要这样实现;
⑤声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态,transient代表对象的临时数据。
⑥序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。为它赋予明确的值。显式地定义serialVersionUID有两种用途:
在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;
在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。
⑦Java有很多基础类已经实现了serializable接口,比如String,Vector等。但是也有一些没有实现serializable接口的;
⑧如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存!这是能用序列化解决深拷贝的重要原因;