Java 加宽/变窄转换的实际应用?
有人能解释一下为什么你会使用加宽或缩小转换吗?我读过很多关于这些的书,但是没有人给我一个实际的例子。谢谢 如果某些代码返回一个包含真/假值的Java 加宽/变窄转换的实际应用?,java,c++,casting,Java,C++,Casting,有人能解释一下为什么你会使用加宽或缩小转换吗?我读过很多关于这些的书,但是没有人给我一个实际的例子。谢谢 如果某些代码返回一个包含真/假值的int,您可以自己将其缩短为bool,这正是它正确表示的。 你也可以做相反的事情 您可以将char扩展为int,以与ascii值进行比较 您可以选取Dog的一个实例,并将其扩展到IAnimal以将其传递给函数 当您知道工厂或其他地方的列表中的动物类型时,您可以将i动物缩短为Dog。您使用隐式转换对不同类型的数值进行计算。例如,如果now() long t
int
,您可以自己将其缩短为bool
,这正是它正确表示的。你也可以做相反的事情 您可以将
char
扩展为int
,以与ascii值进行比较
您可以选取Dog
的一个实例,并将其扩展到IAnimal
以将其传递给函数
当您知道工厂或其他地方的
列表中的动物类型时,您可以将i动物
缩短为Dog
。您使用隐式转换对不同类型的数值进行计算。例如,如果now()
long t = now()
long nextMinute = t + 60
您已经将60(一个int)隐式加宽转换为long,这样您就可以将它添加到t
。能够进行这种转换使数学更容易编码。扩展和缩小转换的一个典型示例是某些文件I/O库的工作方式。通常,文件处理库将具有从文件中读取单个字符的函数/方法。如果有要读取的字符,函数应返回该字符,如果没有剩余字符,则应返回一个sentinel值EOF以发出此信号
由于任何字符都可以出现在文件中,因此函数/方法通常具有以下签名:
int readCharacter();
在这里,函数返回一个int
,如果读取了一个字符,则该值保存一个char
值,否则将EOF
作为哨兵EOF
通常被选择为一个太大而无法保存在char
中的整数。这样,您可以执行以下操作:
while (true) {
int ch = readCharacter();
if (ch == EOF) break;
char actualCharValue = (char) ch;
/* process actualCharValue here */
}
希望这有帮助 (Java)加宽和缩小转换与相关类型之间的转换有关。例如,抽象(超)类与其(子)子类之间的关系;让我们使用java.lang.Number类(抽象)和一个直接子类Integer。我们有:
(superclass) Number
__________/\__________
/ | | \
(concrete subclasses) Integer Long Float Double
加宽转换:如果我们采用特定类型(子类)并尝试将其分配给不太特定的类型(超类),则会发生加宽转换
缩小转换:当我们采用不太特定的类型(超类)并尝试将其分配给更特定的类型(子类)时发生,这需要显式转换
Number n = new Integer(5); // again, widening conversion
Integer i = (Integer) n; // narrowing; here we explicitly cast down to the type we want - in this case an Integer
您需要注意某些问题,例如ClassCastException:
Integer i = new Integer(5);
Double d = new Double(13.3);
Number n;
n = i; // widening conversion - OK
n = d; // also widening conversion - OK
i = (Integer) d; // cannot cast from Double to Integer - ERROR
// remember, current n = d (a Double type value)
i = (Integer) n; // narrowing conversion; appears OK, but will throw ClassCastException at runtime - ERROR
处理此问题的一种方法是使用带有instanceof
关键字的if
语句:
if( n instanceof Integer) {
i = (Integer) n;
}
你为什么要用这个?假设您正在为某个程序创建人员层次结构,您有一个名为“Person”的通用超类,该超类以名字和姓氏作为参数,子类为“Student”、“Teacher”、“Secretary”等。。在这里,您可以首先创建一个泛型person,并(通过继承)将其分配给(比如)一个Student,该Student将在其构造函数中为studenID设置一个额外的变量字段。您可以使用一个方法,将更通用(更广泛)的类型作为参数,并处理该类型的所有子类:
public static void main(String[] args) {
Person p = new Student("John", "Smith", 12345);
printInfo(p);
}
// this method takes the wider Person type as a parameter, though we can send it a narrower type such as Student if we want
public static void printInfo(Person p) {
System.out.println("First: " + p.getFirstName());
System.out.println("Last: " + p.getLastName());
if (p instanceof Student) {
System.out.println( (Student)p).getStudentID() ); // we cast p to Student with Narrow Conversion which allows us to call the getStudentID() method; only after ensuring the p is an instance of Student
}
}
我意识到这可能不是处理事情的理想方式,但为了演示起见,我认为它可以展示一些可能性 拿着这个
转换-专用->通用,当您变得更通用时,它被称为加宽
比如外科医生->医生。在这种情况下,您不需要铸件。因为,外科医生在默认情况下是医生。所以,外科医生能完成所有那些医生能做的事情是很自然的
而另一方面,,
转换-广义->专门化,当您变得更加专业化时,它被称为缩小
比如医生->外科医生。那么,在这种情况下,你必须添加铸造。因为,医生可以是外科医生、内科医生或护士。想想看,如果你让护士给你做手术
很可怕,对吧
希望您能理解。这里有数百万个示例,您应该每天在编写代码时都会遇到它们。我是一名学生,只学了几年编程,以前从未遇到过,对不起。如果我遇到了它,问这个问题就没有意义了,但是谢谢你的批评。在java中,不,你不能将int转换成boolean,这更像是c。。这种怪癖导致了这么多的bug,现在已经不再有趣了。
public static void main(String[] args) {
Person p = new Student("John", "Smith", 12345);
printInfo(p);
}
// this method takes the wider Person type as a parameter, though we can send it a narrower type such as Student if we want
public static void printInfo(Person p) {
System.out.println("First: " + p.getFirstName());
System.out.println("Last: " + p.getLastName());
if (p instanceof Student) {
System.out.println( (Student)p).getStudentID() ); // we cast p to Student with Narrow Conversion which allows us to call the getStudentID() method; only after ensuring the p is an instance of Student
}
}