java方法的调用类型转换_关于java:实现接口,方法调用和类型转换的方法

考虑以下代码

interface MyInterface{

void method(String s);// if we write static modifier we have compile error

}

class MyClass implements MyInterface{

public static void main(String[] args){

myMethod(new Object());//Compile error

}

static void method(String s){...}// compile error

static void myMethod(Number n){...}

}

为什么我们不能在接口中定义静态方法?

为什么不能用静态修饰符实现method()?

当我们引用对象调用MyMethod时,出现了编译错误。据我所知,编译器不会自动强制转换,不是吗?

考虑以下代码

Object someObj;

...

Number n= (Number) someObj;

在本例中,当我们强制转换到Number时,编译器在做什么?

明白我们为什么要将接口方法声明为公共的吗?

@选择不同的主题。与这个问题无关

你问了几个不同的问题,每个问题都应该单独问。第一个可能是接口中为什么不能声明静态方法的副本?.

Why we cant define static method in interface?

默认情况下,接口的所有方法都是public abstract。使用static修饰语没有意义。因为静态方法的调用不是多态的。从某种意义上说,你不能重写它们。只能对类名调用静态方法。好吧,您也可以在某些引用上调用它们,但最终将根据声明的引用类型来解决这一问题。现在,由于该方法在默认情况下是抽象的,所以调用它是没有意义的。它没有任何身体来完成任何任务。

Why we cant implements method() with static modifier?

当您试图向重写方法添加static修饰符时,它不会被视为重写。所以,类本质上有两个不同的方法,具有相同的名称、相同的参数和相同的返回类型。当然,这在类中是不允许的。

注意,您必须显式地向类中的重写方法添加public修饰符,否则代码将无法编译。原因是,您不能降低子类中被重写方法的可见性。

When we are calling myMethod with reference to Object we have compile error. As i understood, compiler doesnt cast automatically, isnt it?

Jave不进行自动缩小转换。您需要显式添加强制转换。但即使它允许,您希望代码的行为如何,因为您正试图用子类引用引用一个超类对象?当然,可以通过在调用方法时添加强制转换来编译代码:

myMethod((Number)new Object());  // This will compile, but fail at runtime

上述调用将在运行时产生一个ClassCastException。

但是,如果您的Object引用引用了Number任何子类的对象,则可以添加一个显式强制转换,这将是类型安全的:

Object obj = new Integer(5);

Number num = (Number)obj;  // This is fine. Because `obj` is referring to an `Integer`.

最后,您的main方法的签名不正确。您缺少public修饰符。

注意,Java 8的接口可以有静态方法。

阿沙吉。是的,Java 8有默认方法,但是我不考虑这里,假设OP还没有使用Java 8。

@Rohit Jain在你的例子中,当我们向Number:Object obj = new Integer(5); Number num = (Number)obj;投射时会发生什么?编译器将(Number)obj解析为对Number的某种引用?

圣安东里奥。编译器将添加强制转换,正如您已经明确说过的。编译器处理引用类型。现在,在运行时,根据引用引用的实际对象,转换可能会失败或成功。因为在您的例子中,实际对象是new Integer(5);,您可以很容易地将其分配给Number引用,所以强制转换成功。

圣安东里奥。如果obj = null;是有效的参考值,那么强制转换也会成功,因为null是有效的参考值。

@Rohit Jain如果我们在编译时显式地进行强制转换会发生什么?编译时的(Number)obj是什么?我认为它是对Number的一些引用,比如编译时的Number someNumber;。是否所有的强制转换都在运行时调用?

圣安东里奥。强制转换总是在运行时完成。使用(Number)obj,您只需将obj的引用类型强制转换为Number。我建议您浏览jls部分-docs.oracle.com/javase/specs/jls/se7/html/jls-5.html jls-5.1

@RohitJain我想了解编译器如何从引用类型obj转换为Number。编译器只是把(Number)obj看作是对Number的引用还是什么?

@Rohit Jain从类型线程到类型对象的转换不需要运行时操作;线程是对象的子类,因此类型线程表达式生成的任何引用都是类型对象的有效引用值。例如,Integer ints= new Integer(2);Number n=ints;为什么编译器知道Integer是Number的子类型?他是否检查了Number的源代码,直到找到Integer或Number的所有子类型?

@St.antario编译器查找Number和Integer的声明,并知道Integer是Number的子类型。什么部分让你困惑?

@Rohit Jain好的,谢谢!最后一个问题:在这种情况下,Number num = (SomeType)obj编译器会查找声明号和sometype,并检查sometype子类型是否为number?请回答是或否。

圣安东里奥。在某种程度上,是的。

圣安东里奥。如果你现在的怀疑是清楚的,那么你可以把答案标为接受。

Why we cant define static method in interface?

基本上,接口设计用于多态性。多态性在接口上调用静态方法时,您如何知道要调用哪个实现?

// Should that invoke MyClass.method or MyOtherImplementation.method?

MyInterface.method("foo");

下一步:

Why we cant implements method() with static modifier?

其思想是在实现接口的某个对象上调用该方法,这使它成为实例方法。

When we are calling myMethod with reference to Object we have compile error. As i understood, compiler doesnt cast automatically, isnt it?

不,编译器不会自动强制转换。没有从Object到Number的隐式转换,因此不能使用Number类型的参数和Object类型的参数调用方法。

What compiler is doing when we cast to Number in this case?

它验证了someObj的值是空的,或者引用了Number或子类的实例。

直到JDK7:

因为静态方法绑定到类。您通常这样调用它们:

MyClass.method("");

您不能覆盖它们。

见1,所有接口方法都是public abstract,不能更改!

不编译器不会自动强制转换

他试着投,但失败了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值