`

Java中bridge方法探秘

    博客分类:
  • Java
 
阅读更多
 
今天在学习郑雨迪老师的《深入拆解 Java 虚拟机》课程,了解Java编译器在一些特殊情况下,会自动创建桥接方法,特在此实践记录一下。

 

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。

 

 

参考

1、Java中的Bridge方法

分享到:
评论

相关推荐

    php-java-bridge_7.2.1_documentation.zip

    2. **Java.inc**:这是一个PHP扩展文件,包含PHP端的接口,用于在PHP代码中调用JavaBridge.jar中的类和方法。 三、集成与使用 在项目中使用PHP-Java-Bridge通常涉及以下步骤: 1. **安装JavaBridge.jar和Java.inc...

    flink-table-api-java-bridge_2.11-1.12.7-API文档-中文版.zip

    赠送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; 赠送...

    JAB(java access bridge)安装和使用

    如果你正在使用的辅助技术(如JAWS或NVDA)支持Java Access Bridge,你需要在辅助技术的设置中启用JAB。具体步骤取决于你使用的辅助技术,通常会在其文档中提供详细说明。 **4. 使用Java Access Bridge** JAB提供...

    flink-table-api-java-bridge_2.12-1.14.3-API文档-中英对照版.zip

    赠送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; 赠送...

    JavaBridge下载

    "java.inc" 文件是JavaBridge中的一个重要组成部分,它包含了一系列预定义的函数声明,这些函数用于在非Java代码中调用Java方法。开发者可以将这些函数包含到他们的项目中,然后就像调用本地函数一样调用Java方法。 ...

    flink-table-api-java-bridge_2.11-1.13.2-API文档-中英对照版.zip

    赠送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; 赠送...

    Java Access bridge 小应用

    要使用Java Access Bridge从C#中获取Java应用程序的信息,你需要导入一个名为`JavaAccessBridge`的库,这个库实现了与Java Access Bridge的接口。在C#中,你可以创建一个`JavaVMInitArgs`对象来配置Java虚拟机(JVM...

    flink-table-api-java-bridge_2.12-1.14.3-API文档-中文版.zip

    赠送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 包含翻译后...

    php-java-bridge 配置包

    start javaw -jar JavaBridge.jar 保存后,双击启动 会有一个提示框选择vmbridge port 默认8080,直接点ok就行了 5.在/demo/下新建test.php内容如下: require_once ( "java/Java.inc" ); header( "content-type:...

    flink-table-api-java-bridge_2.11-1.10.0-API文档-中文版.zip

    赠送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/Java Bridge的JavaBridge.jar、php-servlet.jar和php-script.jar

    当PHP通过HTTP请求与Java服务器交互时,php-servlet接收这些请求,解析它们,并将控制权传递给JavaBridge.jar中的适当方法。这个Servlet使得PHP代码能够以Web服务的方式调用Java服务,实现分布式计算。 3. **...

    JavaBridge

    在提供的文件列表中,`JavaBridge.jar` 是 JavaBridge 的核心库文件,包含实现 PHP 和 Java 交互的类和方法。而 `java` 文件夹可能包含了运行 JavaBridge 所需的其他文件,如配置文件、Java 类库或者示例代码。 ...

    flink-table-api-java-bridge_2.11-1.13.2-API文档-中文版.zip

    赠送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; 赠送...

    Winsoft JavaBridge v3.0 for Delphi Full Source.rar

    它提供了一个简单易用的接口,使开发人员可以在 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的开发源码-PHPJava Bridge.zip 基于java的...

    PHP通过javabridge6.2.1调用 Java的说明及源代码(可运行)

    在PHP中使用JavaBridge,你需要确保你的环境已经安装了Java运行时环境(JRE)以及PHP JavaBridge的相关扩展。 **步骤一:安装与配置** 1. 安装JavaBridge:下载并解压JavaBridge的最新版本(在这个例子中是6.2.1)...

    JavaBridge 2.7.rar

    JavaBridge 是一个软件开发工具,主要用于在Java和Delphi之间建立桥梁,允许开发者利用Java的类库和功能在Delphi环境中编写程序。这个版本是JavaBridge的2.7版,可能包含了对之前版本的一些改进和修复。从压缩包的...

    将PHP/Java Bridge的JavaBridge.jar、php-servlet.jar和php-script.jar

    1. **JavaBridge.jar**:这是PHP/Java Bridge的核心组件,它提供了一个Java服务器端接口,使得PHP能够调用Java类和方法。JavaBridge.jar通过HTTP协议工作,允许PHP代码通过HTTP请求与Java应用程序进行交互。这使得...

    PHP-Java-Bridge

    5. **编写PHP代码**:在PHP脚本中,可以使用`new Java()`来实例化Java类,`$obj-&gt;method()`来调用Java方法,`$obj-&gt;property`来访问Java属性。 **应用场景** PHP-Java-Bridge适用于多种场景: - **数据库访问**:...

Global site tag (gtag.js) - Google Analytics