`
villasy1989
  • 浏览: 77357 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类

java的桥接方法和协变式返回类型

阅读更多
接上篇遇到的bug,总结以下在解决这个bug中遇到的其他问题和学到的新知识,在代码中使用的是ibatis提供的SqlMapClient,因此在setter中进行了new的转化,将demo部署到服务器上之后,启动jboss服务器,服务器无法正常启动,报错主要内容如下:
Bean property 'mysqlReaderMapClient' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
以下是关于这个bug找到的一些资料:
https://jira.springsource.org/browse/SPR-5024
https://jira.springsource.org/browse/SPR-2727
https://jira.springsource.org/browse/SPR-5254
开始因为我们对这个问题并没有一个比较直观的认识与理解,只能走一步看一步,其中仔细看了一些资料,编写了一些测试代码,将主要学习到的知识介绍如下:
第一篇的主题是:Introspection problem: setter not found when corresponding getter uses a covariant return type,第二篇的主题是:Dealing with covariant properties in CachedIntrospectionResult,通过阅读这两篇,主要新接触了两个概念,第一个是“java桥接方法”、“协变返回类型”,将这两个对我而言比较新的名词和大家分享一下:
一、 Java Bridge Method
主要参考了以下两篇感觉比较好的blog:
http://jlife.iteye.com/blog/638407
http://berdy.iteye.com/blog/810488
下面讲一下自己在实践中的一些想法吧,桥接主要是为了兼容jdk 1.4采取的一种措施,桥接方法解决的问题是jdk1.5开始支持泛型,关于泛型的概念,常见的比如:
List<String> strList = new ArrayList<String>();
这就是对泛型比较简单的使用,泛型的好处让从集合中取数据的程序员能够知道自己取的是什么,稍微复杂一些的泛型的应用如下:
public abstract class A<T>{
abstract T get(T t);
}
public class B extends A<String>{
String get(String t);
}
通过泛型指定B中的get返回的类型必须为指定的类型或者子类,其本质就是将原来要在运行期间的检查工作提前到了编译阶段,如果返回的类型不是指定的类型的话,就要报错,为了满足这个特性,同时要能够在老的版本中运行,首先用一个简单的例子去说明这个问题:
在父类中该T会被转换成Object:
public abstract class A<Object>{
abstract Object get(Object  obj);
}
而子类则是:
public class B{
String get(String str);
}
这样在编译时肯定会报错,原因是B继承自A,而A是abstract class,而B并没有overriding掉A中的Object get(Object obj),为了解决这个问题,编译器做了一些工作,当发现我们指定类T的类型时,编译器会在字节码中添加一个桥接方法来overriding掉父类的方法,可以通过查看编译器的字节码可以发现,也可以通过反射来查看类中的方法:
在已有的A.java和B.java的基础上我们添加一个测试类BridgeTest.java,代码如下:
import java.lang.reflect.Method;
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 getjava.lang.String  is Bridge Method? false
class java.lang.Object getjava.lang.Object  is Bridge Method? True
通过分析结果,get返回String的方法不是桥接的,而返回Object是桥接的,这就是编译器做的一些工作。
二、 Covariant Return Type
翻译成中文是协变式返回类型,在介绍这个概念之前先介绍下jdk1.4和jdk1.5中关于函数签名的定义:
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.
也就是说,在jdk1.5中,对于“重写”的判断放宽了条件,子类中方法返回的类型是父类中方法返回类型的子类也算是重写。
可以用下面一个简单的例子来说明:
public class A{
Father get();
}
public class B{
Son get();
}
其中class Son extends Father,这就是协变式返回类型。
分享到:
评论

相关推荐

    java泛型、原始类型、桥接方法

    Java 泛型、原始类型、桥接方法 Java 泛型是 Java 语言中的一种重要特性,用于在编译时检查类型安全性,避免 ...Java 泛型、原始类型和桥接方法是 Java 语言中的一些重要概念,用于确保类型安全性和泛型编程的正确性。

    java桥接模式java桥接模式.doc

    总结,Java桥接模式在设计上提供了一种优雅的方式来解耦抽象和实现,使得两者可以独立发展,这对于大型系统和不断演进的业务需求来说是非常重要的。通过合理地使用桥接模式,开发者可以创建更灵活、可扩展的代码结构...

    桥接模式和策略模式的区别,内含可运行代码和两者详细区别

    桥接模式和策略模式是软件设计模式中的两种重要模式,它们在实现上有着相似之处,但各自的应用场景和设计理念有所不同。下面将详细阐述这两种模式的特点、区别以及它们在实际编程中的应用。 首先,桥接模式(Bridge...

    桥接模式java示例代码

    桥接模式的主要组成部分包括抽象接口(Abstraction)、具体抽象类(Concrete Abstraction)、实现接口(Implementor)和具体实现类(Concrete Implementor)。下面,我们将详细讨论这些组件以及它们在Java中的应用。...

    php调用java,不是http桥接

    本篇将详细介绍一种非HTTP桥接的方式——利用`JavaBridge.jar`实现PHP与Java之间的交互。这种方式不仅避免了HTTP请求所带来的额外开销,还能够更灵活地管理数据传输。 #### 二、准备工作 1. **安装并配置JDK** - ...

    设计模式之桥接模式

    桥接模式(Bridge Pattern)是设计模式中结构型模式的一种,它的主要目的是将抽象部分与实现部分解耦,使得它们可以独立地进行变化...在Java开发中,特别是在需要处理多维度可变性的场景下,桥接模式是非常实用的工具。

    泛型,泛型擦除,桥接方法

    桥接方法是指在子类中重写父类的方法时,Java 编译器生成的桥接方法。例如,在子类中重写父类的 `setValue` 方法时,Java 编译器将生成一个桥接方法,以便在子类中调用父类的方法。桥接方法可以解决方法重写和方法...

    JAVA桥接模式.doc

    总结来说,桥接模式是Java中处理抽象和实现分离的一种有效手段,避免了多继承的复杂性和限制,同时提供了灵活的扩展能力。通过接口和组合,桥接模式能够实现抽象部分和实现部分的独立变化,这对于需要频繁更改或扩展...

    49丨桥接模式:如何实现支持不同类型和渠道的消息推送系统?1

    在JDBC驱动的场景中,桥接模式使得数据库类型和驱动实现的切换变得非常简单,仅需更改配置或代码中的少量部分。虽然桥接模式的应用场景相对有限,但理解并掌握它可以帮助我们在遇到类似问题时,选择更为灵活和可扩展...

    无线桥接设置方法图解

    ### 无线桥接设置方法详解 #### 一、引言 随着无线技术的快速发展和广泛应用,越来越多的企业开始采用无线局域网(WLAN)来满足内部通信需求。特别是在中小企业环境中,无线网络因其灵活性高、成本较低等优势而...

    Java调用IDL程序(IDL Bridge桥接方法)

    Java调用IDL程序需要通过 IDL bridge来完成这一目的,该文件包括对IDL程序编写的规范格式示范,以及提供了本人编写的参考例子,提到在实现调用IDL过程中出现的一些错误以及解决方法。该资源中的word文件较为详细的...

    Java桥接模式原理及用法解析

    Java 桥接模式是一种结构型设计模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响...

    java设计模式-桥接模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中...这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    中兴F427ZA千兆光猫 桥接方法

    中兴F427ZA千兆光猫 桥接方法。 新光猫已经不能用以前直接chrome里改html的方法了,需要root进去修改。 桥接后,iptv和电话均可以正常使用。

    java 桥接模式

    让我们深入探讨一下桥接模式的原理、应用场景以及如何在Java中实现。 **桥接模式的核心思想** 1. **分离接口与实现**:桥接模式将抽象接口与其实现分离开来,使得两者可以独立变化。这样,当需要改变一个部分时,...

    路由器有线二种桥接方法图解.doc

    路由器有线二种桥接方法图解.doc

    路由器WIFI无线桥接方法.pdf

    路由器WIFI无线桥接方法.pdf路由器WIFI无线桥接方法.pdf路由器WIFI无线桥接方法.pdf路由器WIFI无线桥接方法.pdf路由器WIFI无线桥接方法.pdf

    无线路由器桥接方法

    无线路由器桥接方法,小型企业和中小学校使用无线路由器,建立无线覆盖整个单位.

    演示使用java和mysql桥接方式操作数据库

    这里我们通过一个简单的示例来演示如何使用Java和MySQL桥接方式来操作数据库。这个例子主要涉及以下几个知识点: 1. **JDBC (Java Database Connectivity)**: JDBC是Java平台的标准API,用于连接Java应用程序和各种...

Global site tag (gtag.js) - Google Analytics