bridge方法是由Java编译器自动生成的,所以在源代码中无法找到bridge关键字。那么在什么情况下,Java编译器会生成bridge方法呢?
1、防止编译出错:以具体类型继承自一个泛型类,同时被继承的泛型类包含了泛型方法
abstract class A<T> { public abstract T method1(T arg); public abstract T method2(); } class B extends A<String> { public String method1(String arg) { return arg; } public String method2() { return "abc"; } } class C<T> extends A<T> { public T method1(T arg) { return arg; } public T method2() { return null; } }
根据上述代码编译可以得到A、B、C三个类的class文件,分别通过javap -v 指令进行反编译,得到如下结果:
Classfile /D:/A.class Last modified 2018-10-24; size 377 bytes MD5 checksum d9683befc4ab4dab2179f0122aae8c9d Compiled from "Test.java" abstract class A<T extends java.lang.Object> extends java.lang.Object minor version: 0 major version: 52 flags: ACC_SUPER, ACC_ABSTRACT Constant pool: #1 = Methodref #3.#18 // java/lang/Object."<init>":()V #2 = Class #19 // A #3 = Class #20 // java/lang/Object #4 = Utf8 <init> #5 = Utf8 ()V #6 = Utf8 Code #7 = Utf8 LineNumberTable #8 = Utf8 method1 #9 = Utf8 (Ljava/lang/Object;)Ljava/lang/Object; #10 = Utf8 Signature #11 = Utf8 (TT;)TT; #12 = Utf8 method2 #13 = Utf8 ()Ljava/lang/Object; #14 = Utf8 ()TT; #15 = Utf8 <T:Ljava/lang/Object;>Ljava/lang/Object; #16 = Utf8 SourceFile #17 = Utf8 Test.java #18 = NameAndType #4:#5 // "<init>":()V #19 = Utf8 A #20 = Utf8 java/lang/Object { A(); descriptor: ()V flags: Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public abstract T method1(T); descriptor: (Ljava/lang/Object;)Ljava/lang/Object; flags: ACC_PUBLIC, ACC_ABSTRACT Signature: #11 // (TT;)TT; public abstract T method2(); descriptor: ()Ljava/lang/Object; flags: ACC_PUBLIC, ACC_ABSTRACT Signature: #14 // ()TT; } Signature: #15 SourceFile: "Test.java"
Classfile /D:/B.class Last modified 2018-10-24; size 580 bytes MD5 checksum 41ce932c4e2bc9ef13bda9d090ce6ef9 Compiled from "Test.java" class B extends A<java.lang.String> minor version: 0 major version: 52 flags: ACC_SUPER Constant pool: #1 = Methodref #7.#22 // A."<init>":()V #2 = String #23 // abc #3 = Methodref #6.#24 // B.method2:()Ljava/lang/String; #4 = Class #25 // java/lang/String #5 = Methodref #6.#26 // B.method1:(Ljava/lang/String;)Ljava/lang/String; #6 = Class #27 // B #7 = Class #28 // A #8 = Utf8 <init> #9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 method1 #13 = Utf8 (Ljava/lang/String;)Ljava/lang/String; #14 = Utf8 method2 #15 = Utf8 ()Ljava/lang/String; #16 = Utf8 ()Ljava/lang/Object; #17 = Utf8 (Ljava/lang/Object;)Ljava/lang/Object; #18 = Utf8 Signature #19 = Utf8 LA<Ljava/lang/String;>; #20 = Utf8 SourceFile #21 = Utf8 Test.java #22 = NameAndType #8:#9 // "<init>":()V #23 = Utf8 abc #24 = NameAndType #14:#15 // method2:()Ljava/lang/String; #25 = Utf8 java/lang/String #26 = NameAndType #12:#13 // method1:(Ljava/lang/String;)Ljava/lang/String; #27 = Utf8 B #28 = Utf8 A { B(); descriptor: ()V flags: Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method A."<init>":()V 4: return LineNumberTable: line 6: 0 public java.lang.String method1(java.lang.String); descriptor: (Ljava/lang/String;)Ljava/lang/String; flags: ACC_PUBLIC Code: stack=1, locals=2, args_size=2 0: aload_1 1: areturn LineNumberTable: line 8: 0 public java.lang.String method2(); descriptor: ()Ljava/lang/String; flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: ldc #2 // String abc 2: areturn LineNumberTable: line 11: 0 public java.lang.Object method2(); descriptor: ()Ljava/lang/Object; flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokevirtual #3 // Method method2:()Ljava/lang/String; 4: areturn LineNumberTable: line 6: 0 public java.lang.Object method1(java.lang.Object); descriptor: (Ljava/lang/Object;)Ljava/lang/Object; flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC Code: stack=2, locals=2, args_size=2 0: aload_0 1: aload_1 2: checkcast #4 // class java/lang/String 5: invokevirtual #5 // Method method1:(Ljava/lang/String;)Ljava/lang/String; 8: areturn LineNumberTable: line 6: 0 } Signature: #19 // LA<Ljava/lang/String;>; SourceFile: "Test.java"
Classfile /D:/C.class Last modified 2018-10-24; size 416 bytes MD5 checksum eec9e342b1c9698264f2d7d94f8dec7c Compiled from "Test.java" class C<T extends java.lang.Object> extends A<T> minor version: 0 major version: 52 flags: ACC_SUPER Constant pool: #1 = Methodref #3.#18 // A."<init>":()V #2 = Class #19 // C #3 = Class #20 // A #4 = Utf8 <init> #5 = Utf8 ()V #6 = Utf8 Code #7 = Utf8 LineNumberTable #8 = Utf8 method1 #9 = Utf8 (Ljava/lang/Object;)Ljava/lang/Object; #10 = Utf8 Signature #11 = Utf8 (TT;)TT; #12 = Utf8 method2 #13 = Utf8 ()Ljava/lang/Object; #14 = Utf8 ()TT; #15 = Utf8 <T:Ljava/lang/Object;>LA<TT;>; #16 = Utf8 SourceFile #17 = Utf8 Test.java #18 = NameAndType #4:#5 // "<init>":()V #19 = Utf8 C #20 = Utf8 A { C(); descriptor: ()V flags: Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method A."<init>":()V 4: return LineNumberTable: line 15: 0 public T method1(T); descriptor: (Ljava/lang/Object;)Ljava/lang/Object; flags: ACC_PUBLIC Code: stack=1, locals=2, args_size=2 0: aload_1 1: areturn LineNumberTable: line 17: 0 Signature: #11 // (TT;)TT; public T method2(); descriptor: ()Ljava/lang/Object; flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aconst_null 1: areturn LineNumberTable: line 21: 0 Signature: #14 // ()TT; } Signature: #15 // <T:Ljava/lang/Object;>LA<TT;>; SourceFile: "Test.java"
可以看到B中生成了两个bridge方法(B.class的#72和#83的ACC_BRIDGE修饰符),而C中并没有。事实上,由于Java中存在泛型擦除机制,因而在编译A类的时候,它里面定义的方法都是以Object来表示的,如果没有bridge方法,B类根本没有办法覆盖A类中的abstract方法,也就无法通过编译。而C类由于在编译时所有的泛型也都是通过Object类表示,所以它覆盖了A类中的abstract方法,也就不需要再生成bridge方法了。
ps:若A中泛型形式为 T extend XXX,则泛型擦除后以XXX表示。
事实上,B类中的bridge方法在调用上也有一些区别:
public class MainTest { public static void main(String[] args) { B b = new B(); b.method1("abc"); A<String> a = new B(); a.method1("abc"); } }
编译该类,然后再使用java -v指令反编译,得到如下结果:
Classfile /D:/MainTest.class Last modified 2018-10-24; size 447 bytes MD5 checksum 96102fe169c54abdab88af079ff0aea1 Compiled from "MainTest.java" public class MainTest minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #8.#17 // java/lang/Object."<init>":()V #2 = Class #18 // B #3 = Methodref #2.#17 // B."<init>":()V #4 = String #19 // abc #5 = Methodref #2.#20 // B.method1:(Ljava/lang/String;)Ljava/lang/String; #6 = Methodref #21.#22 // A.method1:(Ljava/lang/Object;)Ljava/lang/Object; #7 = Class #23 // MainTest #8 = Class #24 // java/lang/Object #9 = Utf8 <init> #10 = Utf8 ()V #11 = Utf8 Code #12 = Utf8 LineNumberTable #13 = Utf8 main #14 = Utf8 ([Ljava/lang/String;)V #15 = Utf8 SourceFile #16 = Utf8 MainTest.java #17 = NameAndType #9:#10 // "<init>":()V #18 = Utf8 B #19 = Utf8 abc #20 = NameAndType #25:#26 // method1:(Ljava/lang/String;)Ljava/lang/String; #21 = Class #27 // A #22 = NameAndType #25:#28 // method1:(Ljava/lang/Object;)Ljava/lang/Object; #23 = Utf8 MainTest #24 = Utf8 java/lang/Object #25 = Utf8 method1 #26 = Utf8 (Ljava/lang/String;)Ljava/lang/String; #27 = Utf8 A #28 = Utf8 (Ljava/lang/Object;)Ljava/lang/Object; { public MainTest(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=1 0: new #2 // class B 3: dup 4: invokespecial #3 // Method B."<init>":()V 7: astore_1 8: aload_1 9: ldc #4 // String abc 11: invokevirtual #5 // Method B.method1:(Ljava/lang/String;)Ljava/lang/String; 14: pop 15: new #2 // class B 18: dup 19: invokespecial #3 // Method B."<init>":()V 22: astore_2 23: aload_2 24: ldc #4 // String abc 26: invokevirtual #6 // Method A.method1:(Ljava/lang/Object;)Ljava/lang/Object; 29: pop 30: return LineNumberTable: line 4: 0 line 5: 8 line 7: 15 line 8: 23 line 9: 30 } SourceFile: "MainTest.java"
可以看见,引用类型为B的B实例,直接调用B类中的method1(java.lang.String)方法,而引用类型为A的B实例,则是调用B类中的桥接方法method1(java.lang.Object)方法,在桥接方法中再调用method1(java.lang.String)方法,即B.class的#89。
2、实现Java语言重写语义:子类方法返回值是父类相应方法返回值的子类型
在Java语言中,方法重写要求父类方法和子类方法的方法名和参数类型相同;而在JVM中,方法重写的判断依据为方法名、方法描述符相同,而方法描述符包含参数类型和返回值类型。因此,Java语言中表现为重写语义的代码,在JVM中可能就是非重写的情况。针对这种情况,Java编译器会通过生成bridge方法来实现Java语言中的重写语义。
interface Customer { boolean isVIP(); } class Merchant { public Number actionPrice(double price, Customer customer) { // ... return 0; } } class NaiveMerchant extends Merchant { @Override public Double actionPrice(double price, Customer customer) { // ... return 0D; } }
根据上述代码编译可以得到Customer、Merchant、NaiveMerchant三个类的class文件,分别通过javap -v 指令进行反编译,得到如下结果:
Classfile /D:/Customer.class Last modified 2018-10-24; size 115 bytes MD5 checksum a61b62d5f33f0fe496f31d7d16fd671e Compiled from "Test.java" interface Customer minor version: 0 major version: 52 flags: ACC_INTERFACE, ACC_ABSTRACT Constant pool: #1 = Class #7 // Customer #2 = Class #8 // java/lang/Object #3 = Utf8 isVIP #4 = Utf8 ()Z #5 = Utf8 SourceFile #6 = Utf8 Test.java #7 = Utf8 Customer #8 = Utf8 java/lang/Object { public abstract boolean isVIP(); descriptor: ()Z flags: ACC_PUBLIC, ACC_ABSTRACT } SourceFile: "Test.java"
Classfile /D:/Merchant.class Last modified 2018-10-24; size 345 bytes MD5 checksum db00af1d8ffcecafbf260caa21213b49 Compiled from "Test.java" class Merchant minor version: 0 major version: 52 flags: ACC_SUPER Constant pool: #1 = Methodref #4.#13 // java/lang/Object."<init>":()V #2 = Methodref #14.#15 // java/lang/Integer.valueOf:(I)Ljava/lang/Integer; #3 = Class #16 // Merchant #4 = Class #17 // java/lang/Object #5 = Utf8 <init> #6 = Utf8 ()V #7 = Utf8 Code #8 = Utf8 LineNumberTable #9 = Utf8 actionPrice #10 = Utf8 (DLCustomer;)Ljava/lang/Number; #11 = Utf8 SourceFile #12 = Utf8 Test.java #13 = NameAndType #5:#6 // "<init>":()V #14 = Class #18 // java/lang/Integer #15 = NameAndType #19:#20 // valueOf:(I)Ljava/lang/Integer; #16 = Utf8 Merchant #17 = Utf8 java/lang/Object #18 = Utf8 java/lang/Integer #19 = Utf8 valueOf #20 = Utf8 (I)Ljava/lang/Integer; { Merchant(); descriptor: ()V flags: Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 5: 0 public java.lang.Number actionPrice(double, Customer); descriptor: (DLCustomer;)Ljava/lang/Number; flags: ACC_PUBLIC Code: stack=1, locals=4, args_size=3 0: iconst_0 1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 4: areturn LineNumberTable: line 8: 0 } SourceFile: "Test.java"
Classfile /D:/NaiveMerchant.class Last modified 2018-10-24; size 429 bytes MD5 checksum c466aec3c5469abf26cdb273eb30d02c Compiled from "Test.java" class NaiveMerchant extends Merchant minor version: 0 major version: 52 flags: ACC_SUPER Constant pool: #1 = Methodref #5.#15 // Merchant."<init>":()V #2 = Methodref #16.#17 // java/lang/Double.valueOf:(D)Ljava/lang/Double; #3 = Methodref #4.#18 // NaiveMerchant.actionPrice:(DLCustomer;)Ljava/lang/Double; #4 = Class #19 // NaiveMerchant #5 = Class #20 // Merchant #6 = Utf8 <init> #7 = Utf8 ()V #8 = Utf8 Code #9 = Utf8 LineNumberTable #10 = Utf8 actionPrice #11 = Utf8 (DLCustomer;)Ljava/lang/Double; #12 = Utf8 (DLCustomer;)Ljava/lang/Number; #13 = Utf8 SourceFile #14 = Utf8 Test.java #15 = NameAndType #6:#7 // "<init>":()V #16 = Class #21 // java/lang/Double #17 = NameAndType #22:#23 // valueOf:(D)Ljava/lang/Double; #18 = NameAndType #10:#11 // actionPrice:(DLCustomer;)Ljava/lang/Double; #19 = Utf8 NaiveMerchant #20 = Utf8 Merchant #21 = Utf8 java/lang/Double #22 = Utf8 valueOf #23 = Utf8 (D)Ljava/lang/Double; { NaiveMerchant(); descriptor: ()V flags: Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method Merchant."<init>":()V 4: return LineNumberTable: line 12: 0 public java.lang.Double actionPrice(double, Customer); descriptor: (DLCustomer;)Ljava/lang/Double; flags: ACC_PUBLIC Code: stack=2, locals=4, args_size=3 0: dconst_0 1: invokestatic #2 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double; 4: areturn LineNumberTable: line 16: 0 public java.lang.Number actionPrice(double, Customer); descriptor: (DLCustomer;)Ljava/lang/Number; flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC Code: stack=4, locals=4, args_size=3 0: aload_0 1: dload_1 2: aload_3 3: invokevirtual #3 // Method actionPrice:(DLCustomer;)Ljava/lang/Double; 6: areturn LineNumberTable: line 12: 0 } SourceFile: "Test.java"
可以看到NaiveMerchant中生成了一个bridge方法(NaiveMerchant.class的#58的ACC_BRIDGE修饰符),此时Java编译器生成的bridge方法是为了实现Java语言中的重写语义。
看下调用情况:
public class MainTest { public static void main(String[] args) { NaiveMerchant m1 = new NaiveMerchant(); m1.actionPrice(0D, null); Merchant m2 = new NaiveMerchant(); m2.actionPrice(0D, null); } }编译该类,然后再使用java -v指令反编译,得到如下结果:
Classfile /D:/MainTest.class Last modified 2018-10-24; size 447 bytes MD5 checksum 1ef5eb90881c3b3da897da96ba57e894 Compiled from "MainTest.java" public class MainTest minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #7.#16 // java/lang/Object."<init>":()V #2 = Class #17 // NaiveMerchant #3 = Methodref #2.#16 // NaiveMerchant."<init>":()V #4 = Methodref #2.#18 // NaiveMerchant.actionPrice:(DLCustomer;)Ljava/lang/Double; #5 = Methodref #19.#20 // Merchant.actionPrice:(DLCustomer;)Ljava/lang/Number; #6 = Class #21 // MainTest #7 = Class #22 // java/lang/Object #8 = Utf8 <init> #9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 main #13 = Utf8 ([Ljava/lang/String;)V #14 = Utf8 SourceFile #15 = Utf8 MainTest.java #16 = NameAndType #8:#9 // "<init>":()V #17 = Utf8 NaiveMerchant #18 = NameAndType #23:#24 // actionPrice:(DLCustomer;)Ljava/lang/Double; #19 = Class #25 // Merchant #20 = NameAndType #23:#26 // actionPrice:(DLCustomer;)Ljava/lang/Number; #21 = Utf8 MainTest #22 = Utf8 java/lang/Object #23 = Utf8 actionPrice #24 = Utf8 (DLCustomer;)Ljava/lang/Double; #25 = Utf8 Merchant #26 = Utf8 (DLCustomer;)Ljava/lang/Number; { public MainTest(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=4, locals=3, args_size=1 0: new #2 // class NaiveMerchant 3: dup 4: invokespecial #3 // Method NaiveMerchant."<init>":()V 7: astore_1 8: aload_1 9: dconst_0 10: aconst_null 11: invokevirtual #4 // Method NaiveMerchant.actionPrice:(DLCustomer;)Ljava/lang/Double; 14: pop 15: new #2 // class NaiveMerchant 18: dup 19: invokespecial #3 // Method NaiveMerchant."<init>":()V 22: astore_2 23: aload_2 24: dconst_0 25: aconst_null 26: invokevirtual #5 // Method Merchant.actionPrice:(DLCustomer;)Ljava/lang/Number; 29: pop 30: return LineNumberTable: line 3: 0 line 4: 8 line 6: 15 line 7: 23 line 8: 30 } SourceFile: "MainTest.java"可以看见,引用类型为NaiveMerchant的NaiveMerchant实例,直接调用NaiveMerchant类中的public java.lang.Double actionPrice(double, Customer)方法,而引用类型为Merchant的NaiveMerchant实例,则是调用NaiveMerchant类中的桥接方法public java.lang.Number actionPrice(double, Customer)方法,在桥接方法中再调用public java.lang.Double actionPrice(double, Customer)方法,即NaiveMerchant.class的#64。
相关推荐
2. **Java.inc**:这是一个PHP扩展文件,包含PHP端的接口,用于在PHP代码中调用JavaBridge.jar中的类和方法。 三、集成与使用 在项目中使用PHP-Java-Bridge通常涉及以下步骤: 1. **安装JavaBridge.jar和Java.inc...
赠送jar包:flink-table-api-java-bridge_2.11-1.12.7.jar; 赠送原API文档:flink-table-api-java-bridge_2.11-1.12.7-javadoc.jar; 赠送源代码:flink-table-api-java-bridge_2.11-1.12.7-sources.jar; 赠送...
如果你正在使用的辅助技术(如JAWS或NVDA)支持Java Access Bridge,你需要在辅助技术的设置中启用JAB。具体步骤取决于你使用的辅助技术,通常会在其文档中提供详细说明。 **4. 使用Java Access Bridge** JAB提供...
"java.inc" 文件是JavaBridge中的一个重要组成部分,它包含了一系列预定义的函数声明,这些函数用于在非Java代码中调用Java方法。开发者可以将这些函数包含到他们的项目中,然后就像调用本地函数一样调用Java方法。 ...
赠送jar包:flink-table-api-java-bridge_2.11-1.13.2.jar; 赠送原API文档:flink-table-api-java-bridge_2.11-1.13.2-javadoc.jar; 赠送源代码:flink-table-api-java-bridge_2.11-1.13.2-sources.jar; 赠送...
赠送jar包:flink-table-api-java-bridge_2.12-1.14.3.jar; 赠送原API文档:flink-table-api-java-bridge_2.12-1.14.3-javadoc.jar; 赠送源代码:flink-table-api-java-bridge_2.12-1.14.3-sources.jar; 赠送...
要使用Java Access Bridge从C#中获取Java应用程序的信息,你需要导入一个名为`JavaAccessBridge`的库,这个库实现了与Java Access Bridge的接口。在C#中,你可以创建一个`JavaVMInitArgs`对象来配置Java虚拟机(JVM...
赠送jar包:flink-table-api-java-bridge_2.12-1.14.3.jar 赠送原API文档:flink-table-api-java-bridge_2.12-1.14.3-javadoc.jar 赠送源代码:flink-table-api-java-bridge_2.12-1.14.3-sources.jar 包含翻译后...
start javaw -jar JavaBridge.jar 保存后,双击启动 会有一个提示框选择vmbridge port 默认8080,直接点ok就行了 5.在/demo/下新建test.php内容如下: require_once ( "java/Java.inc" ); header( "content-type:...
赠送jar包:flink-table-api-java-bridge_2.11-1.10.0.jar; 赠送原API文档:flink-table-api-java-bridge_2.11-1.10.0-javadoc.jar; 赠送源代码:flink-table-api-java-bridge_2.11-1.10.0-sources.jar; 赠送...
当PHP通过HTTP请求与Java服务器交互时,php-servlet接收这些请求,解析它们,并将控制权传递给JavaBridge.jar中的适当方法。这个Servlet使得PHP代码能够以Web服务的方式调用Java服务,实现分布式计算。 3. **...
在提供的文件列表中,`JavaBridge.jar` 是 JavaBridge 的核心库文件,包含实现 PHP 和 Java 交互的类和方法。而 `java` 文件夹可能包含了运行 JavaBridge 所需的其他文件,如配置文件、Java 类库或者示例代码。 ...
赠送jar包:flink-table-api-java-bridge_2.11-1.13.2.jar; 赠送原API文档:flink-table-api-java-bridge_2.11-1.13.2-javadoc.jar; 赠送源代码:flink-table-api-java-bridge_2.11-1.13.2-sources.jar; 赠送...
它提供了一个简单易用的接口,使开发人员可以在 Delphi 中调用和使用 Java 类和方法。该组件通过 Java 虚拟机 (JVM) 实现了 Delphi 和 Java 之间的桥接,使得在 Delphi 中调用 Java 代码变得简单和方便。使用 ...
基于java的开发源码-PHPJava Bridge.zip 基于java的开发源码-PHPJava Bridge.zip 基于java的开发源码-PHPJava Bridge.zip 基于java的开发源码-PHPJava Bridge.zip 基于java的开发源码-PHPJava Bridge.zip 基于java的...
在PHP中使用JavaBridge,你需要确保你的环境已经安装了Java运行时环境(JRE)以及PHP JavaBridge的相关扩展。 **步骤一:安装与配置** 1. 安装JavaBridge:下载并解压JavaBridge的最新版本(在这个例子中是6.2.1)...
JavaBridge 是一个软件开发工具,主要用于在Java和Delphi之间建立桥梁,允许开发者利用Java的类库和功能在Delphi环境中编写程序。这个版本是JavaBridge的2.7版,可能包含了对之前版本的一些改进和修复。从压缩包的...
1. **JavaBridge.jar**:这是PHP/Java Bridge的核心组件,它提供了一个Java服务器端接口,使得PHP能够调用Java类和方法。JavaBridge.jar通过HTTP协议工作,允许PHP代码通过HTTP请求与Java应用程序进行交互。这使得...
5. **编写PHP代码**:在PHP脚本中,可以使用`new Java()`来实例化Java类,`$obj->method()`来调用Java方法,`$obj->property`来访问Java属性。 **应用场景** PHP-Java-Bridge适用于多种场景: - **数据库访问**:...