Bridge Method直译过来就是桥接方法。从字面意思可以很容易的理解出这个方法是在连接两个东西。那到底是在连接什么呢?废话少说,上代码:
abstract class A<T> {
abstract T get(T t);
}
class B extends A<String> {
@Override
String get(String s) {
return "";
}
}
public class TestBridge {
public static void main(String[] args) {
Class<B> clazz = B.class;
Method[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
System.out.println(getMethodInfo(m) + " is Bridge Method? " + m.isBridge());
}
}
public static String getMethodInfo(Method m){
StringBuilder sb = new StringBuilder();
sb.append(m.getReturnType()).append(" ");
sb.append(m.getName());
Class[]params = m.getParameterTypes();
for (int i = 0; i < params.length; i++) {
sb.append(params[i].getName()).append(" ");
}
return sb.toString();
}
}
运行上面的代码,可以看到输出结果如下:
[class java.lang.String get] is Bridge Method? false
[class java.lang.Object get] is Bridge Method? true
或许你现在诧异了,怎么B类中只定义了一个方法,现在怎么出现了两个呢?而且返回类型和参数类型还不同。话说这个是java5中的泛型所带来的结果了。针对上面的这段代码分析下:
在java5之前,你可以往一个集合里扔任何你想扔的对象。往集合中放对象的人很爽了。但是从集合中去对象的人就头大了。你不知道你下个取到的对象将会是什么类型的。不知道转成什么类型,你也就只能使用所有Object的方法了,这样就毫无意义了。所以在java5中提供了泛型这一新特性。程序员在写代码的时候可以指定集合可以存放对象的类型。然后将这些类型检查的事情交给编译器去做,减少了程序员的工作。
上面代码中<>中的T和String就是指定类的参数类型。T代表一种泛型,告诉编译器,一旦有类指定了T这个参数的实际类,那么get方法返回的类型也必须为同一个类(当然也可以是这个类的子类;这个也是java5中的协变式返回新特性),如果不是,就必须报错提示;将原来的运行时可能出现的错误提前到编译期了。那么,假设你是java5编译器的设计者,你会如何来设计让编译器能实现这个特性,同时能保证编译出来的字节码可以在老版本的jdk中运行呢?java5编译器中作了个很巧妙的设计——桥接方法。
下面来说说java5编译器是如何来编译上面的代码:
abstract class A<T> {
abstract T get(T t);
}
对于A类,编译器看到<>中指定的T参数后,会用Object把类中的其他T参数替换。因为在jdk中根本就不存在T这个类嘛。替换后就成了下面这样子。
abstract class A {
abstract Object get(Object obj);
}
上面这个过程称为类型擦除。对于B类,它继承了A类,指定了T参数为String。如果还按照以前那么编译,那编译的类就是:
class B extends A {
String get(String s) {
return "";
}
}
这样在运行时肯定会报错,因为B继承了A,而A又是asbtract类,B还没overriding A中Object get()方法。如何解决这个错误呢?java5编译器在编译的时候做了些手脚。当编译器发现你指定了类型参数,便会在编译的字节码中添加一个桥接方法。这个可以查看B的反编译代码就知道了。
class B extends A {
//编译器添加的方法
Object get(Object s) {
return (Object) get((String) s);
}
String get(String s) {
return "";
}
}
那么编译器会在什么情况下添加桥接方法呢?这个就不细说了,感兴趣的可以自己尝试。下面再说说协变式返回,什么是协变式返回呢?先可以对比下java1.4和java5中对于重写的定义:
In Java 1.4, and earlier, one method can override another if the signatures match exactly.
In Java 5, a method can override another if the arguments match exactly but the return type of the overriding method, if it is a subtype of the return type of the other method.
也就是说,对于重写的判断放宽了条件,子类中方法返回的类型是父类中方法返回类型的子类也是重写,听起来有点绕,看下面这段代码:
class A{
Father get(){}
}
class B extends A{
@Override
Son get(){}
}
class Father{}
class Sun extends Father{}
也就是B中的get()方法返回Son类也是重载。如何实现的呢?同样是使用桥接方法。
关于桥接方法更多的可以参考JLS
Create Frame, Synchronize, Transfer Control
分享到:
相关推荐
本篇将详细介绍一种非HTTP桥接的方式——利用`JavaBridge.jar`实现PHP与Java之间的交互。这种方式不仅避免了HTTP请求所带来的额外开销,还能够更灵活地管理数据传输。 #### 二、准备工作 1. **安装并配置JDK** - ...
Bridge ( 桥接模式 ) Composite ( 组合模式 ) Decorator ( 装饰模式 ) Facade ( 外观模式 ) Flyweight ( 享元模式 ) Proxy ( 代理模式 ) Chain of Responsibility ( 责任链模式 ) Command ( 命令模式 ) ...
7. Bridge(桥接) 8. Composite(组合) 9. Decorator(装饰) 10. Facade(外观) 11. Flyweight(享元) 12. Proxy(代理) 行为型 13. Interpreter(解释器) 14. Template Method(模板方法) 15. ...
7. Bridge(桥接) 8. Composite(组合) 9. Decorator(装饰) 10. Facade(外观) 11. Flyweight(享元) 12. Proxy(代理) 行为型 13. Interpreter(解释器) 14. Template Method(模板方法) 15. Chain of ...
23种Python设计模式示例演示源码包,比如包括了工厂模式、Bridge桥接模式、Builder构建模式、Facade外观模式、Adapter适配器模式,Composite组合模式、Decorator装饰器模式,FactoryMethod工厂方法模式、Flyweight享...
2、Bridge 桥接 3、Composite 组合模式 4、Decorator装饰者 5、Façade 外观、门面 6、Flyweight 享元模式 7、Proxy 代理模式 11个行为模式: 1、Chain of Responsibility 职责链 2、Command 命令 3、...
12. BRIDGE(桥接)的意图:B选项正确,桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。 13. COMPOSITE(组合)的意图:C选项正确,组合模式将对象组合成树形结构,以表示部分-整体的层次结构。 ...
Bridge(桥接) Composite(组合) [Done] Decorator(装饰) Facade(外观) Flyweight(享元) Proxy(代理) ##行为型 Interpreter(解释器) [Done] Template Method(模板方法) Chain of Responsibility(责任...
现在,JavaScript可以在网页中通过`window.androidBridge.callAndroidMethod`来调用`AppBridge`的`callAndroidMethod`方法。例如: ```javascript ()">点击调用Android方法 function callAndroid() { window....
★附录A介绍了剩下的设计模式:Bridge(桥接)、Builder(生成器)、Chainof Responsibility(责任链)、Flyweight(蝇量)、Interpreter(解释器)、Mediator(中介者)、Memento(备忘录)、Prototype(原型)、...
除了这些模式,ASP.NET还广泛使用其他设计模式,如单例模式(Singleton)用于管理全局资源,工厂方法模式(Factory Method)用于创建对象,策略模式(Strategy)用于定义算法族,以及观察者模式(Observer)用于事件...
观察者模式(Observer Pattern) 建造者模式(Builder Pattern) 解释器模式(Interpreter Pattern) 命令模式(Command Pattern) 模板方法模式(Template Method Pattern) 桥接模式(Bridge Pattern) 适配器模式(Adapter ...
- 桥接模式(Bridge) - 组合模式(Composite) - 外观模式(Facade) - 享元模式(Flyweight) - 观察者模式(Observer) - 模板方法模式(Template Method) - 策略模式(Strategy) - 责任链模式(Chain of ...
十、模板方法模式(Template Method) 模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 这些设计模式是软件开发中的宝贵...
4.2 Bridge(桥接)—对象结构型 模式 100 4.3 Composite(组成)—对象结构型 模式 107 4.4 Decorator(装饰)—对象结构型 模式 115 4.5 FACADE(外观)—对象结构型 模式 121 4.6 Flyweight(享元)—...
4.2 Bridge(桥接)—对象结构型 模式 100 4.3 Composite(组成)—对象结构型 模式 107 4.4 Decorator(装饰)—对象结构型 模式 115 4.5 FACADE(外观)—对象结构型 模式 121 4.6 Flyweight(享元)—对象结构型 ...
4.2 Bridge(桥接)—对象结构型 模式 100 4.3 Composite(组成)—对象结构型 模式 107 4.4 Decorator(装饰)—对象结构型 模式 115 4.5 FACADE(外观)—对象结构型 模式 121 4.6 Flyweight(享元)—对象结构型 ...
4.2 Bridge(桥接)—对象结构型 模式 100 4.3 Composite(组成)—对象结构型 模式 107 4.4 Decorator(装饰)—对象结构型 模式 115 4.5 FACADE(外观)—对象结构型 模式 121 4.6 Flyweight(享元)—对象结构型 ...
4.2 Bridge(桥接)—对象结构型 模式 100 4.3 Composite(组成)—对象结构型 模式 107 4.4 Decorator(装饰)—对象结构型 模式 115 4.5 FACADE(外观)—对象结构型 模式 121 4.6 Flyweight(享元)—...
4.2 Bridge(桥接)—对象结构型 模式 100 4.3 Composite(组成)—对象结构型 模式 107 4.4 Decorator(装饰)—对象结构型 模式 115 4.5 FACADE(外观)—对象结构型 模式 121 4.6 Flyweight(享元)—对象结构型 ...