java的字段能被重写吗?

问题的来源

在看周志明先生的《深入理解java虚拟机》的时候看到这么一句:在Java语言中字段是无法被重载的,两个字段的数据类型、修饰符不管是否相同,都必须使用不一样的名称,但是对于字节码来讲,如果两个字段的描述符不一致,那字段重名就是合法的。
描述符指的是字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。

简单的理解就是Java语言中(也就是我们编码时)字段不能重名,但是在字节码层面字段重名、描述符不同是合法的。

这里提到重载,自然而然的就会想到重写,我们都知道方法是可以重写的,那么一连串的问题来啦!
什么是重写?
为什么说方法是可以重写的呢?
字段能不能被重写呢?

带着这几个问题我进行了以下测试

测试方法重写

父类中有一个print()方法,子类继承父类,重写print(),通过结果可以看出,子类直接调用print()方法和将子类的对象赋值给父类的引用然后调用print(),打印的都是M-SubClass1,都是调用了子类的print()体现了多态

class SuperClass1 {
    public String print() {
        return "M-SuperClass1";
    }
}

class SubClass1 extends SuperClass1 {
    @Override
    public String print() {
        return "M-SubClass1";
    }
}

public static void main(String[] args) {

	SubClass1 subClass1 = new SubClass1();
	// 将子类的对象赋值给父类的引用
	SuperClass1 superClass1 = subClass1;

	System.out.println("-----------------方法------------------");
	System.out.println("superClass1.print() " + superClass1.print());
	System.out.println("subClass1.print()   " + subClass1.print());
}

结果

-----------------方法------------------
superClass1.print() M-SubClass1
subClass1.print()   M-SubClass1
测试字段重写

父类中有一个str字段,子类继承父类,子类中也有一个str字段,通过结果可以看出,直接打印子类str字段的结果为SubClass2,先将子类的对象赋值给父类的引用,然后打印父类的str字段的结果为SuperClass2。也就是说字段重写没有成功
另外给子类的str字段添加@Override注解时会报错,也从另一个方面说明了字段不能重写。

class SuperClass2 {
    public String str = "SuperClass2";
}

class SubClass2 extends SuperClass2 {
    // @Override 加上会报错
    public String str = "SubClass2";
}

public static void main(String[] args) {

	SubClass2 subClass2 = new SubClass2();
	// 将子类的对象赋值给父类的引用
	SuperClass2 superClass2 = subClass2;

	System.out.println("-----------------字段------------------");
	System.out.println("superClass2.str     " + superClass2.str);
	System.out.println("subClass2.str       " + subClass2.str);
}

结果

-----------------字段------------------
superClass2.str     SuperClass2
subClass2.str       SubClass2
三个问题

1、什么是重写?
我个人认为,在继承关系中,能体现多态特性的行为才叫做重写。
2、为什么说方法是可以重写的呢?
因为体现了多态,从测试方法重写中可以看出,将子类的对象赋值给父类的引用然后调用print(),最终调用的是子类的方法。
3、字段能不能被重写呢?
字段不能被重写,从测试字段重写中可以看出:将子类的对象赋值给父类的引用,然后打印,结果是父类的str,没有体现多态。

完整代码

https://gitee.com/zhaobingshuang/codes/h9v50zdseqclk8itj2fw335

自定义字段类型解析器是一种用于处理复杂对象的方式。通过自定义字段类型解析器,我们可以将复杂对象转换为数据库中的特定类型,或者将数据库中的特定类型转换为复杂对象。 下面是一个示例,演示如何自定义字段类型解析器: ```java import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MyFieldTypeHandler implements TypeHandler<Object> { @Override public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { // 将复杂对象转换为数据库中的特定类型,并设置到PreparedStatement中 // 例如,将对象转换为JSON字符串,将JSON字符串设置到PreparedStatement中 ps.setString(i, convertObjectToJson(parameter)); } @Override public Object getResult(ResultSet rs, String columnName) throws SQLException { // 从ResultSet中获取数据库中的特定类型,并将其转换为复杂对象 // 例如,从JSON字符串中解析出对象 return convertJsonToObject(rs.getString(columnName)); } @Override public Object getResult(ResultSet rs, int columnIndex) throws SQLException { // 从ResultSet中获取数据库中的特定类型,并将其转换为复杂对象 // 例如,从JSON字符串中解析出对象 return convertJsonToObject(rs.getString(columnIndex)); } @Override public Object getResult(CallableStatement cs, int columnIndex) throws SQLException { // 从CallableStatement中获取数据库中的特定类型,并将其转换为复杂对象 // 例如,从JSON字符串中解析出对象 return convertJsonToObject(cs.getString(columnIndex)); } private String convertObjectToJson(Object object) { // 将对象转换为JSON字符串的逻辑 // 例如,使用Jackson库将对象转换为JSON字符串 return jsonConverter.convertToJson(object); } private Object convertJsonToObject(String json) { // 将JSON字符串转换为对象的逻辑 // 例如,使用Jackson库将JSON字符串转换为对象 return jsonConverter.convertToObject(json); } } ``` 在上面的示例中,我们实现了`TypeHandler`接口,并重写了其中的方法。在`setParameter`方法中,我们将复杂对象转换为数据库中的特定类型,并将其设置到`PreparedStatement`中。在`getResult`方法中,我们从`ResultSet`中获取数据库中的特定类型,并将其转换为复杂对象。 通过使用自定义字段类型解析器,我们可以灵活地处理复杂对象,并将其存储到数据库中或从数据库中读取出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值