看起来我只是两次声明它的类型,一次是在括号中,一次是在圆括号之外。我正在谈论的一些例子:
HttpURLConnection my_urlConnection = (HttpURLConnection) url1.openConnection();
Button my_button = (Button) findViewById(R.id.btn1);
TextView my_textview = (TextView) findViewById(R.id.textview1);
这是什么意思?
答案 0 :(得分:5)
这是演员。括号中的类型基本上告诉编译器“尝试将此后的任何内容视为此类型”。这通常是必要的,因为该方法的返回类型是父类,您需要一个子类。
例如,在第二行代码中,您写道:
Button my_button = (Button) findViewById(R.id.btn1);
findViewById
不会返回Button
。它返回View
。即使它返回的视图实际上 是Button
,但它肯定不知道。这是一个只知道View
的愚蠢方法。因此,您需要告诉Java“假设这是一个按钮并将其转换为适当的类型”。如果你这样做了......
View my_view = findViewById(R.id.btn1);
......你不需要演员。您不需要编写(View)findViewById(R.id.btn1);
,因为方法的返回类型和您为其分配的变量的类型都匹配。如果要将子类分配给父类,则也不需要强制转换。没有演员,这是合法的:
View my_view = new Button(); // No cast necessary. Button is a subclass of View and can be used anywhere View is used.
这不合法:
Button my_button = new View(); // View can't be automatically converted to Button unless it was a Button to begin with.
另请注意,您无法使用强制转换将任何类型转换为任何其他类型。如果对象是该类型,或者是该类型的父类或子类,则只能将对象强制转换为该类型。例如:
try {
View my_view = (View)(new Activity());
}
catch(ClassCastException e)
{
// This will always happen. Activity isn't a parent or subclass of View.
}
有一个tutorial here可能对您有帮助。
答案 1 :(得分:4)
这是对该类型的强制转换,就像在普通Java中一样。
答案 2 :(得分:1)
openConnection
的返回类型为URLConnection
,而不是HttpURLConnection
,但如果您知道您要打开的网址类型是HTTP网址,那么您知道自己是取回HttpURLConnection
(URLConnection
的子类)。
同样,findViewById
的返回类型为View
,但如果您知道自己正在查找Button
或TextView
,则表示您知道自己是Button
取回TextView
或View
(View
的子类),而不仅仅是原始ClassCastException
。
所以类型名称是强制转换返回预期的具体类型的值:你说“我知道实际的对象至少是这个子类型,而不仅仅是那个超类型,所以改变我对它的引用来使用子类型。“这样您就可以访问这些子类型提供的功能,而不是仅限于访问基本类型的常用功能。 (如果“cast”是一个不常见的术语,see this tutorial的“铸造对象”部分。)
当然,如果你错了,你得到的东西实际上就是其中一个子类,你会得到一个Map
。
这并非特定于Android开发,它是几种编程语言常见的一般概念。这就像Bad Old Days,当我们没有泛型时,所以每当你从get
检索某些内容时,你必须将它转换为你知道的内容,因为{{1}的返回类型} Object
:
Map map = new HashMap();
// ...later...
Thingy t = (Thingy)map.get("myThingy");
现在,我们可以说“此地图中有Thingy
个实例”就像这样,而不必这样做 - 参数化Map
的{{1}}方法返回引用类型适当地:
get
但是在你引用的代码中没有使用它,因为API不支持它,或者它只是来自泛型的遗留代码。