用于转换的 Java 规则
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2233902/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java rules for casting
提问by alan
When can a certain object be cast into another object? Does the casted object have to be a subtype of the other object? I'm trying to figure out the rules...
什么时候可以将某个对象转换为另一个对象?铸造对象是否必须是另一个对象的子类型?我正在尝试找出规则...
Edit: I realized that I didn't explain my issue at all: basically I am casting an object to an interface type. However, at run-time, I get a java.lang.ClassCastException
. What needs to happen with my object so that I can cast it to this interface? Does it have to implement it?
编辑:我意识到我根本没有解释我的问题:基本上我将对象转换为接口类型。但是,在运行时,我得到一个java.lang.ClassCastException
. 我的对象需要做什么才能将它转换到这个接口?它必须执行吗?
Thanks
谢谢
回答by Anon.
You can cast if the runtime type of an object is a subtype of what you're trying to cast it into.
如果对象的运行时类型是您尝试将其转换为的子类型,则您可以进行转换。
EDIT:
编辑:
Yes, the object that you're trying to cast will need to implement the interface in order for you to cast it successfully.
是的,您尝试转换的对象需要实现接口才能成功转换。
回答by codaddict
In Java there are two types of reference variable casting:
在 Java 中有两种类型的引用变量转换:
Downcasting: If you have a reference variable that refers to a subtype object, you can assign it to a reference variable of the subtype. You must make an explicit cast to do this, and the result is that you can access the subtype's members with this new reference variable.
Upcasting: You can assign a reference variable to a supertype reference variable explicitly or implicitly. This is an inherently safe operation because the assignment restricts the access capabilities of the new variable.
Downcasting:如果您有一个引用变量引用子类型对象,则可以将其分配给子类型的引用变量。您必须进行显式转换才能执行此操作,结果是您可以使用此新引用变量访问子类型的成员。
Upcasting:您可以显式或隐式地将引用变量分配给超类型引用变量。这是一个本质上安全的操作,因为赋值限制了新变量的访问能力。
Yes, you need to implement the interface directly or indirectlyto enable assigning your class object reference to the interface type.
是的,您需要直接或间接实现接口,才能将您的类对象引用分配给接口类型。
回答by Vincent Ramdhanie
If:
如果:
interface MyInterface{}
class MyClass implements MyInterface{}
Then
然后
MyClass m = new MyClass();
MyInterface i = (MyInterface)m;
is possible.
是可能的。
回答by Steve B.
There's an intuitive way of thinking about this - you're not changing an object with a cast, you're only doing something that would already be permitted if the type was known - inotherwords, you can only cast to a type that your object already is. So just look "up" the object chain to see what kinds apply to your object.
有一种直观的思考方式——你不是用强制转换来改变对象,你只是在做一些如果类型已知就已经被允许的事情——换句话说,你只能强制转换为你的对象已经存在的类型是。因此,只需查看“向上”对象链,看看哪些类型适用于您的对象。
So you can cast to an interface onlyif it's defined somewhere higher up in the chain (e.g. if your classes parent implements it, etc. etc). It has to be explicit - from your question it sounds like you may be thinking that if you implement method "void foo()" then you should be able to cast to an interface that defines the method "void foo()" - this is sometimes described as "duck typing"(if it quacks like a duck, it's a duck) but is not how java works.
因此,只有当它在链中更高的某个地方定义时,您才能转换为接口(例如,如果您的类父级实现了它,等等)。它必须是明确的 - 从你的问题听起来你可能会想,如果你实现方法“void foo()”,那么你应该能够转换到定义方法“void foo()”的接口 - 这是有时被描述为“鸭子打字”(如果它像鸭子一样嘎嘎叫,那就是鸭子)但不是 java 的工作方式。
回答by finnw
This will work:
这将起作用:
class Foo implements Runnable {
public void run() {}
}
Foo foo = new Foo();
System.out.println((Runnable) foo);
But this will not:
但这不会:
class Bar {
public void run() {}
}
Bar bar = new Bar();
System.out.println((Runnable) bar);
Because although Bar
has a run()
method that couldimplement Runnable.run()
, Bar
is not declared to implement Runnable
so it cannot be cast to Runnable
.
因为尽管Bar
有run()
这种方法可以实现Runnable.run()
,Bar
是不是政府在宣布实行Runnable
所以它不能被转换为Runnable
。
Java requires that you declare implemented interfaces by name. It does not have duck typing, unlike some other languages such as Pythonand Go
回答by Bhargav Solanki
Suppose we want to cast d object to A,
假设我们要将 d 对象强制转换为 A,
A a = (C)d;
A a = (C)d;
So internally 3 rules have been checked by Compiler and JVM. The compiler is checking first 2 rules at Compile time and JVM will check last one rule at Runtime.
所以内部3条规则已经被编译器和JVM检查过。 编译器在编译时检查前 2 条规则,JVM 将在运行时检查最后一条规则。
Rule 1 (Compile time checking):
规则 1(编译时检查):
Type of 'd' and C must have some relation (child to parent or parent to child or same time).If there is no relationship then we will get a compile error(inconvertible types).
'd' 的类型和 C 必须有某种关系(子对父或父对子或同时)。如果没有关系,那么我们将得到一个编译错误(不可转换的类型)。
Rule 2 (Compile time checking):
规则 2(编译时检查):
'C' must be either same type or derived type(subclass) of 'A' otherwise we will get a compile error(incompatible types).
'C' 必须是 'A' 的相同类型或派生类型(子类),否则我们将收到编译错误(类型不兼容)。
Rule 3 (Runtime Exception):
规则 3(运行时异常):
Runtime object type of 'd' must be same or derived a type of 'C' otherwise we will get a runtime exception (ClassCastException Exception).
'd' 的运行时对象类型必须相同或派生为 'C' 类型,否则我们将得到运行时异常(ClassCastException Exception)。
Find following examples to get more idea,
查找以下示例以获得更多想法,
String s = new String("hello"); StringBuffer sb = (StringBuffer)s; // Compile error : Invertible types because there is no relationship between.
Object o = new String("hello"); StringBuffer sb = (String)o; // Compile error : Incompatible types because String is not child class of StringBuffer.
Object o = new String("hello"); StringBuffer sb = (StringBuffer)o; // Runtime Exception : ClassCastException because 'o' is string type and trying to cast into StingBuffer and there is no relationship between String and StringBuffer.