1.extends
用于类继承类,用法:
class
+子类名+extends
+父类名+{}
class Animal{}//父类 class cat extends Animal{}//子类用extends实现继承
注意:一个类只能用extends
关键字声明继承一个父类
用于接口继承接口,用法:
interface
+接口名+extends
+接口名+{}
interface Clippers {} interface Warriors {} interface Lakers extends Clippers,Warriors {}//接口类用extends关键字继承其他接口(可多个)
注意:
接口不能用
extends
声明继承别的类接口只能用
extends
声明继承别的接口,且可以继承多个接口当一个类用
implements
实现了一个接口时,不仅要实现该接口的方法,也要实现该接口继承的接口的方法
2.implements
用于声明一个类实现了一个接口类,用法:
class
+类名+implements
+接口名+{}
class Nets implements Clippers,Warriors{}//用implements关键字声明实现了两个接口类
注意:
一个普通类可以
implements
关键字声明实现多个接口,但必须实现所有接口中的所有方法抽象类实现接口,可以不用实现接口的方法(因为抽象类中可以有抽象方法)
意义:可以用
implements
关键字声明实现多个接口来实现类似多继承
3.final
使用方法:
修饰类,使该类不能被继承
修饰方法,使该方法不能被子类重写 (仍可以被继承和调用)
修饰属性,使该属性的值不能被修改(使为常量)
修饰局部变量,使该变量不能被修改(局部常量)
使用细节:
final
修饰的属性在定义时必须赋初值,且不能修改,可以在以下位置赋初值
定义时(显示初始化)
在构造器中
在代码块中
static final
:全局常量
如果
final
修饰的属性是静态(static
)的,则不能在构造器中赋初值,原因:静态属性要求在类加载时就有初值,而构造器在创建对象时才被调用,所以可能导致调用静态属性时没有创建对象而没有给静态属性赋值final
不能修饰构造方法,没有意义被
final
和static
同时修饰的属性在调用时不会导致类的加载,效率更高
4.native
基本介绍:
native
用来修饰方法,被修饰的方法即成为了一个Java调用但非Java代码实现的接口(本地方法) ,该方法在外部可以用任何语言去实现
"A native method is a java method whose implementation is provided by non-java code."
使用方法:
native
修饰方法的位置必须在方法返回类型之前,和方法访问修饰符位置没有要求,如:public native int hashCode();
native
细节:
native
方法没有方法体,也没有{}
用
native
修饰后的方法不能用abstract
修饰,因为abstract
指明该方法无实现体,而native
方法是有实现体的,只是用非Java
代码实现的native
方法的返回类型可以是任意类型如果一个有
native
方法的类被继承,子类会继承这个native
方法,并且可以用java
语言重写
使用JNI(Java Native Interface)
与其他语言交互
JNI
是Java
平台的一部分,它允许Java
代码和其他语言写的代码进行交互。
使用步骤:
编写带有
native
方法的java
类,生成.java
文件使用
javac
命令编译生成.class
文件使用
javah -jni 类名
生成.h
文件使用
C/C++(或者其他编程语言)
实现native
方法,创建.cpp(或其他)
文件将
C/C++
编写的文件创建动态链接库(生成DLL文件)native
方法中使用System.loadLibrary()
方法加载动态库,将DLL文件名作为参数传入,这时候再运行.java
程序即可实现对本地方法的调用
详细步骤参考
native意义:
Java
无法直接访问到操作系统底层(如系统硬件),但通过使用native
关键字修饰方法可以借用其他的语言来扩展Java
程序的功能,提高程序的效率
5.static
修饰变量,成为静态变量或者类变量
使用方法:
访问修饰符+``static``+数据类型+变量名
注意事项:
静态变量会被类的所有对象实例所共享,并且在类加载的时候就会初始化。
静态变量的访问方法(遵守相关访问权限):
类名.静态变量名
或者对象名.静态变量名
修饰方法,成为静态方法或者类方法
使用方法:
访问修饰符+``static``+返回数据类型+方法名+{}
注意事项:
调用方法(遵守相关访问权限):
类名.静态方法名
或者对象名.静态方法名
静态方法和普通方法都是随着类加载而加载,将结构信息存储在方法区
静态方法中不允许使用
this
和super
关键字静态方法中只能访问静态变量和静态方法
普通方法可以访问静态成员和普通成员
修饰代码块,成为静态代码块:
静态代码块会在类加载时被加载,优先级和静态属性一样,有多个静态代码块和静态属性时,初始化顺序按定义顺序执行
好处:static
关键字的使用,将类中的一些成员修饰成静态的,这样我们不需要创建该类的对象就可以调用该成员,大大提高了编程效率
6.transient
基本介绍:
transient
用于修饰实现了Serilizable
接口的类中的成员变量,在该类的实例对象进行序列化处理时,被transient
修饰的成员变量不会进行序列化。
使用例子:
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; public class outStream { public static void main(String[] args) throws IOException { String filePath = "d:\Cat.txt"; ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath)); oos.writeObject(new Cat("小花猫", 3)); oos.close(); } } class Cat implements Serializable { private String name; private int age; //没有用transient修饰 public Cat(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Car{" + "name='" + name + ''' + ", age=" + age + '}'; } } public class inStream { public static void main(String[] args) throws IOException, ClassNotFoundException { String filePath = "d:\Cat.txt"; ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath)); System.out.println(ois.readObject()); ois.close(); } }
可以在Cat.txt
文件内看到两个成员变量都能被序列化,并且能被反序列化读出信息。
当小花猫觉得自己的年龄是隐私不想被读出时,用transient
修饰成员变量age
:
...... private String name; private transient int age; //使用transient修饰 ......
这时在Cat.txt
文件中可以看到只有name
一个成员变量被序列化,反序列化后的成员变量age
读出的是int类型的默认值,说明对于transient
修饰的成员变量,在类的实例对象序列化的过程中会被忽略
transient
细节
对
transient
修饰的成员变量可以理解为:不会参与进行对象的序列化和反序列化过程,生存周期仅存于调用者的内存而不会写进磁盘里进行持久化static
修饰的成员变量(静态变量)也是不可序列化的,不论被transient
修饰与否
因为序列化是保存的实例对象的状态,而静态变量保存的是类的状态
transient
关键字只能修饰变量,不能修饰方法和类transient
关键字不能修饰局部变量如
transient
关键字修饰的是自定义类的变量,则该类需要实现Serilizable
接口
注意:
实现Serilizable
接口的类的实例对象是自动进行序列化的,如果序列化对象的类实现的是Externalizable
接口,则序列化不会自动进行,需要实现接口内的方法指定要序列化的变量,这时与有无Transient
修饰无关
7.synchronized
基本介绍:
关键字synchronized
可以保证在同一时刻,只有一个线程可以执行被synchronized
修饰的方法或代码块
线程同步:
程序中多个线程都要使用同一个方法,而这个方法用synchronized
进行了修饰,在多个线程调用这个方法时必须遵循同步机制
线程同步机制:
当一个线程使用synchronized
修饰的方法时,其他线程想使用这个方法时就必须等待,直到这个线程使用完synchronized
方法
synchronized使用方法:
普通同步方法:
public synchronized void m () {}
public class syn implements Runnable { static int i = 0; public static void main(String[] args) throws InterruptedException { syn test = new syn(); Thread t1 = new Thread(test); Thread t2 = new Thread(test); t1.start(); t2.start(); } public synchronized void increase() {//被synchronized修饰的同步方法 System.out.println(Thread.currentThread().getName() + "调用:" + i++); } @Override public void run() { for (int j = 0; j < 100; j++) { increase(); } } }
两个线程同时调用一个对象的一个同步方法,由于一个对象只有一把锁,所以只有一个线程能够获得该对象的锁,另一个线程无法获得,就不能调用该对象的synchronized
方法,需要等对象被释放后才能调用。
从运行结果中可以证明线程1抢到了锁,线程0必须等待线程1执行完毕,否则不能访问该同步方法。
静态同步方法:
public static synchronized void m () {}
public class syn implements Runnable { static int i = 0; public static void main(String[] args) throws InterruptedException { syn test = new syn(); syn test1 = new syn(); Thread t1 = new Thread(test);//传入实例对象test Thread t2 = new Thread(test1);//传入实例对象test1 t1.start(); t2.start(); } public static synchronized void increase() {//同步静态方法 System.out.println(Thread.currentThread().getName() + "调用:" + i++); } @Override public void run() { for (int j = 0; j < 100; j++) { increase(); } } }
虽然两个线程实例化了两个不同的对象,但是synchronized
修饰的是静态方法,两个线程仍然发生了互斥,因为静态方法是依附与类的而不是对象,线程1先抢到了类的锁,而线程0必须等待线程1执行完毕释放才能调用同步方法
同步代码块:
synchronized(object) {}
public class syn implements Runnable { static Object object = new Object();//共享对象 public static void main(String[] args) throws InterruptedException { syn test = new syn(); syn test1 = new syn(); Thread t1 = new Thread(test); Thread t2 = new Thread(test1); t1.start(); t2.start(); } @Override public void run() { synchronized (object) {//代码块用静态成员变量上锁 for (int j = 0; j < 100; j++) { System.out.println(Thread.currentThread().getName() + "调用第" + j + "次"); } } } }
同步代码块用两个实例变量共享的静态成员object
对象来上锁,虽然是两个线程实例化两个不同的对象,但是对整个syn
类来说只有一个共享的object
对象,所以只有一把锁,每当有线程来访问代码块时需持有锁,对象锁被其他线程持有时需等待。线程1需要等线程0执行完毕才能访问同步代码块
同步的局限性:
由于同步的方法或代码块只能同一时间让一个线程访问,所以会导致程序的执行效率降低
尽可能让synchronized
修饰的范围最小化,来减少互斥对程序执行带来的影响
8.volatile
基本介绍:
volatile
用于修饰变量,用volatile
修饰的变量的值被某个线程修改时,会强制将修改的值立即写入主存中,主存中的值更新会使得缓存中的该变量的值失效,对比与非volatile
变量,可能会被其他线程读取到更新前的值。
使用方法:
//现在有线程1和线程2同时执行下列代码 int i = 0; i = i + 1;
执行完毕后预想的结果是 i = 2
;但是可能存在这样一种情况:两个线程先同时把i的值读取到自己的工作内存中,然后再分别执行 i = i + 1
的操作,再将结果写入主存,这样两个线程写入的都是 i = 1
,最终 i
的结果是 1
,而不是 2
但如果 i
是 volatile
修饰的变量就会不一样了,在一个线程修改 i
的值后,会立即强制在主存中更新 i
的值,这样会导致另一个线程的工作内存中 i
的缓存值无效,所以另一个线程再次从主存中读取新的 i
的值,这样保证了i
的值是最新并正确的
并发编程的三大概念:
原子性:执行一个操作时,要么全部步骤执行完毕且不被中断,要么就不执行
x = 100;//是原子性操作 y = x;//不是原子性操作,可分解为:1.先读取x的值 2.将x的值写入主存 x ++;//不是原子性操作,可分解为:1.读取x的值 2.进行加一操作 3.写入主存
可见性:多个线程对同一个变量进行操作时,一个线程修改了变量的值,其他线程能立即看到修改的值
有序性:程序执行的顺序按照代码的先后顺序执行
volatile
的意义
保证了不同线程对变量进行修改时的可见性:因为对于
volatile
变量来说,被修改后新值对其他线程来说是立即可见的保证了有序性:
volatile
禁止了指令重排,它能保证在对volatile
修饰的变量进行操作时,之前的代码语句已经全部被执行,并且后面的语句都未执行,但是对其他语句的顺序是不做保证的
注意: volatile
不能保证原子性,因为不能保证对变量的操作是原子性操作
9.this
在方法中修饰属性,this理解为
当前对象
,用来区别成员方法和形参,通常省略修饰方法,this理解为当前对象,通常省略;不能在静态方法中使用
调用构造器,在构造器中使用
this(形参列表)
显式调用指定的其他构造器必须在首行调用其他构造器
一个构造器中不能调用多个其他构造器
不能在构造器中调用递归调用,不能成环调用
10.super
super可以理解为:父类的
修饰属性:去父类中找对应属性,用来区分子父类重名的属性
修饰方法:调用重写之前的方法
调用构造器:使用
super(形参列表)
指定调用父类构造器super(形参列表)
必须放在构造器的首行super(形参列表)
和this(形参列表)
只能二选一在构造器首行如果没有显式声明
super(形参列表)
或this(形参列表)
则默认调用父类的空参构造器super()
(如果此时父类中没有空参构造器就会报错)不能在静态方法中使用
当一个方法和属性被static属性修饰时,这些方法和属性是优先于对象加载进入内存的,是随着类的加载而加载的;this是当前对象的引用,super是指父类的引用,当静态方法加载进内存进栈时,如果在静态方法中有this和super关键字时,this和super也被加载到了内存,但是这个时候并没有对象的引用,this和super没有初始化,所有编译会报错。
10.1.子类对象实例化的过程
11.访问修饰符
public修饰类:
一个类中最多只能有一个public类,且文件名要和public类一致
如果没有public类,文件名可以任意
以上是Java重要的关键字有哪些的详细内容。更多信息请关注PHP中文网其他相关文章!

javaispopularforcross-platformdesktopapplicationsduetoits“ writeonce,runanywhere”哲学。1)itusesbytbytybytecebytecodethatrunsonanyjvm-platform.2)librarieslikeslikeslikeswingingandjavafxhelpcreatenative-lookingenative-lookinguisis.3)

在Java中编写平台特定代码的原因包括访问特定操作系统功能、与特定硬件交互和优化性能。1)使用JNA或JNI访问Windows注册表;2)通过JNI与Linux特定硬件驱动程序交互;3)通过JNI使用Metal优化macOS上的游戏性能。尽管如此,编写平台特定代码会影响代码的可移植性、增加复杂性、可能带来性能开销和安全风险。

Java将通过云原生应用、多平台部署和跨语言互操作进一步提升平台独立性。1)云原生应用将使用GraalVM和Quarkus提升启动速度。2)Java将扩展到嵌入式设备、移动设备和量子计算机。3)通过GraalVM,Java将与Python、JavaScript等语言无缝集成,增强跨语言互操作性。

Java的强类型系统通过类型安全、统一的类型转换和多态性确保了平台独立性。1)类型安全在编译时进行类型检查,避免运行时错误;2)统一的类型转换规则在所有平台上一致;3)多态性和接口机制使代码在不同平台上行为一致。

JNI会破坏Java的平台独立性。1)JNI需要特定平台的本地库,2)本地代码需在目标平台编译和链接,3)不同版本的操作系统或JVM可能需要不同的本地库版本,4)本地代码可能引入安全漏洞或导致程序崩溃。

新兴技术对Java的平台独立性既有威胁也有增强。1)云计算和容器化技术如Docker增强了Java的平台独立性,但需要优化以适应不同云环境。2)WebAssembly通过GraalVM编译Java代码,扩展了其平台独立性,但需与其他语言竞争性能。

不同JVM实现都能提供平台独立性,但表现略有不同。1.OracleHotSpot和OpenJDKJVM在平台独立性上表现相似,但OpenJDK可能需额外配置。2.IBMJ9JVM在特定操作系统上表现优化。3.GraalVM支持多语言,需额外配置。4.AzulZingJVM需特定平台调整。

平台独立性通过在多种操作系统上运行同一套代码,降低开发成本和缩短开发时间。具体表现为:1.减少开发时间,只需维护一套代码;2.降低维护成本,统一测试流程;3.快速迭代和团队协作,简化部署过程。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

Dreamweaver CS6
视觉化网页开发工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

SublimeText3 Linux新版
SublimeText3 Linux最新版

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)