精华内容
下载资源
问答
  • c++类型转换

    万次阅读 多人点赞 2019-05-29 19:45:08
    c 风格的转换的格式很简单(TYPE) EXPRESSION,但是 c 风格的类型转换有不少的缺点,有的时候用 c 风格的转换是不合 适的,因为它可以在任意类型之间转换,比如你可以把一个指向 const 对象的指针转换 成指向非 ...
    类型转换有 c 风格的,当然还有 c++风格的。c 风格的转换的格式很简单(TYPE) EXPRESSION,但是 c 风格的类型转换有不少的缺点,有的时候用 c 风格的转换是不合 适的,因为它可以在任意类型之间转换,比如你可以把一个指向 const 对象的指针转换 成指向非 const 对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的 指针,这两种转换之间的差别是巨大的,但是传统的 c 语言风格的类型转换没有区分这 些。还有一个缺点就是,c 风格的转换不容易查找,他由一个括号加上一个标识符组成, 而这样的东西在 c++程序里一大堆。所以 c++为了克服这些缺点,引进了 4 新的类型转换操作符。
    • c++提供了四种类型转换,分别适用于其他场景
    static_cast静态类型转换。
    reinterpreter_cast重新解释类型转换。
    dynamic_cast子类和父类之间的多态类型转换。
    const_cast去掉const属性转换

    1. static_cast 静态类型转换

    • static_cast<目标类型>(标识符)
    • 所谓的静态,即在编译期内即可决定其类型的转换,用的也是最多的一种。
    #include <iostream>
    using namespace std; 
    
    int main(void)
    {
    	double dPi = 3.1415926;
    	int num1 = (int)dPi;    //c语言的旧式类型转换
    	int num2 = dPi;         //隐式类型转换
    	// 静态的类型转换:   
    	// 在编译的时 进⾏行基本类型的转换 能替代c⻛风格的类型转换 可以进⾏行⼀一部分检查     
    	int num3 = static_cast<int> (dPi); //c++的新式的类型转换运算符   
    	cout << "num1:" << num1 << " num2:" << num2 << " num3:" << num3 << endl;
    	return 0;
    }
    

    2. dynamic_cast 子类与父类之间的多态类型准换

    • dynamic_cast<目标类型>(标识符)
    • 用于多态中父子类之间的多态转换
    #include<iostream>
    
    class Animal {
    public:
    	virtual void cry() = 0;
    };
    
    class Dog : public Animal
    {
    public:
    	virtual void cry()
    	{
    		std::cout << "旺旺" << std::endl;
    	}
    	void dohome()
    	{
    		std::cout << "看家" << std::endl;
    	}
    };
    
    class Cat : public Animal
    {
    public:
    	virtual void cry()
    	{
    		std::cout << "喵喵" << std::endl;
    	}
    	void dohome()
    	{
    		std::cout << "抓老鼠" << std::endl;
    	}
    };
    
    int main()
    {
    	Animal* base = NULL;
    	base = new Cat();
    	base->cry();
    
    	//⽤用于将⽗父类指针转换成⼦子类,
    	Dog	*pDog = dynamic_cast<Dog*>(base); //此时转换时失败的,因为父类指针现在指向的对象是猫,所以转换狗是失败的。
    	                                      //转换失败返回空(NULL)
    	if (pDog != NULL)
    	{
    		pDog->cry();
    		pDog->dohome();
    	}
    
    	Cat* pCat = dynamic_cast<Cat*>(base); //此时转换成功,成功将父类指针转换成子类指针
    	if (pCat != NULL)
    	{
    		pCat->cry();
    		pCat->dohome();
    	}
    
    	system("pause");
    	return 0;
    }
    

    3. const_cast 去掉const属性转换

    • const_cast<目标类型>(标识符):目标类型只能是指针或者引用
    #include<iostream>
    
    class A {
    public:
    	int data;
    };
    
    int main()
    {
    	const A a = { 200 };
    	A a1 = const_cast<A>(a);    //错误,const_cast 目标类型只能是引用或者指针
    	a1.data = 100;
    
    	A& a2 = const_cast<A&>(a);
    	a2.data = 100;
    	std::cout << a.data << ' ' << a2.data << std::endl;
    
    	A* a3 = const_cast<A*>(&a);
    	a3->data = 100;
    	std::cout << a.data << ' ' << a3->data << std::endl;
    
    	const int x = 3;
    
    	int& x1 = const_cast<int&>(x);
    	x1 = 200;
    	std::cout << x << ' ' << x1 << std::endl;
    
    	int* x2 = const_cast<int*>(&x);
    	*x2 = 300;
    	std::cout << x << ' ' << *x2 << std::endl;
    
    	system("pause");
    	return 0;
    }
    

    reinterpret_cast 重新解释类型转换

    • reinterpret_cast<目标类型>(标识符)
    • 数据的二进制重新解释,但是不改变其值。
    #include<iostream>
    
    class Animal {
    public:
    	void cry()
    	{
    		std::cout << "Animal cry" << std::endl;
    	}
    };
    
    class Book {
    public:
    	void look()
    	{
    		std::cout << "Book look " << std::endl;
    	}
    };
    
    int main()
    {
    	Animal* a = new Animal();
    	a->cry();
    	Book* b = reinterpret_cast<Book*>(a);  //强制类型的转换
    	b->look();
    	system("pause");
    	return 0;
    }
    
    展开全文
  • C++: 隐式类型转换和显式类型转换

    千次阅读 2019-11-06 12:49:44
    1) 算术转换(Arithmetic conversion) : 在混合类型的算术表达式中, 最宽的数据类型成为目标转换类型。 intival=3; doubledval=3.14159; ival+dval;//ival被提升为double类型 2)一种类型表达式赋值给另一种类型的...

     

    第1部分. 隐式类型转换


    又称为“标准转换”,包括以下几种情况:
    1) 算术转换(Arithmetic conversion) : 在混合类型的算术表达式中, 最宽的数据类型成为目标转换类型。

    int ival = 3;
    double dval = 3.14159;
    
    ival + dval;//ival被提升为double类型

    2)一种类型表达式赋值给另一种类型的对象:目标类型是被赋值对象的类型

    int *pi = 0; // 0被转化为int *类型
    ival = dval; // double->int

    例外:void指针赋值给其他指定类型指针时,不存在标准转换,编译出错

    3)将一个表达式作为实参传递给函数调用,此时形参和实参类型不一致:目标转换类型为形参的类型

    extern double sqrt(double);

    cout << "The square root of 2 is " << sqrt(2) << endl;
    //2被提升为double类型:2.0

    4)从一个函数返回一个表达式,表达式类型与返回类型不一致:目标转换类型为函数的返回类型

    double difference(int ival1, int ival2)
    {
        return ival1 - ival2;
        //返回值被提升为double类型
    }

     

    第2部分. 显式类型转换


    被称为“强制类型转换”(cast)
    C     风格: (type-id)
    C++风格: static_castdynamic_castreinterpret_cast、和const_cast..

     

    关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的《C++ 的设计和演化》。最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_cast, dynamic_cast。标准C++中有四个类型转换符:static_castdynamic_castreinterpret_cast、和const_cast。下面对它们一一进行介绍。
     

    static_cast

     

    用法:static_cast < type-id > ( expression )

     

    说明:该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。

     

    来源:为什么需要static_cast强制转换?
    情况1:void指针->其他类型指针
    情况2:改变通常的标准转换
    情况3:避免出现可能多种转换的歧义




    它主要有如下几种用法:
    • 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
    • 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
    • 把void指针转换成目标类型的指针(不安全!!)
    • 把任何类型的表达式转换成void类型。
    注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。
     

    dynamic_cast

     

    用法:dynamic_cast < type-id > ( expression )

     

    说明:该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。


    来源:为什么需要dynamic_cast强制转换?
    简单的说,当无法使用virtual函数的时候

    典型案例:
    Wicrosoft公司提供给我们一个类库,其中提供一个类Employee.以头文件Eemployee.h和类库.lib分发给用户
    显然我们并无法得到类的实现的源代码
    //Emplyee.h
    class Employee 
    {
    public:
        virtual int salary();
    };
    
    class Manager : public Employee
    {
    public: 
        int salary();
    };
    
    class Programmer : public Employee
    {
    public:
        int salary();
    };

    我们公司在开发的时候建立有如下类:
    class MyCompany
    {
    public:
        void payroll(Employee *pe);
        //
    };
    
    void MyCompany::payroll(Employee *pe)
    {
        //do something
    }

    但是开发到后期,我们希望能增加一个bonus()的成员函数到W$公司提供的类层次中。
    假设我们知道源代码的情况下,很简单,增加虚函数:
    //Emplyee.h
    class Employee 
    {
    public:
        virtual int salary();
        virtual int bonus();
    };
    
    class Manager : public Employee
    {
    public: 
        int salary();
    };
    
    class Programmer : public Employee
    {
    public:
        int salary();
        int bonus();
    };
    
    //Emplyee.cpp
    
    int Programmer::bonus()
    {
        //
    }
    
    
    payroll()通过多态来调用bonus()
    class MyCompany
    {
    public:
        void payroll(Employee *pe);
        //
    };
    
    void MyCompany::payroll(Employee *pe)
    {
        //do something
        //pe->bonus();
    }

    但是现在情况是,我们并不能修改源代码,怎么办?dynamic_cast华丽登场了!
    在Employee.h中增加bonus()声明,在另一个地方定义此函数,修改调用函数payroll().重新编译,ok

     

    //Emplyee.h
    class Employee 
    {
    public:
        virtual int salary();
    };
    
    class Manager : public Employee
    {
    public: 
        int salary();
    };
    
    class Programmer : public Employee
    {
    public:
        int salary();
        int bonus();//直接在这里扩展
    };
    
    //somewhere.cpp
    
    int Programmer::bonus()
    {
        //define
    }
    
     
    class MyCompany
    {
    public:
        void payroll(Employee *pe);
        //
    };
    
    void MyCompany::payroll(Employee *pe)
    {
        Programmer *pm = dynamic_cast<Programmer *>(pe);
        
        //如果pe实际指向一个Programmer对象,dynamic_cast成功,并且开始指向Programmer对象起始处
        if(pm)
        {
            //call Programmer::bonus()
        }
        //如果pe不是实际指向Programmer对象,dynamic_cast失败,并且pm = 0
        else
        {
            //use Employee member functions
        }
    }
    
    

    dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

    在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
    class Base
    {
    public:
        int m_iNum;
        virtual void foo();
    };
    
    class Derived:public Base
    {
    public:
        char *m_szName[100];
    };
    
    void func(Base *pb)
    {
        Derived *pd1 = static_cast<Derived *>(pb);
    
        Derived *pd2 = dynamic_cast<Derived *>(pb);
    }

    在上面的代码段中,
    如果pb实际指向一个Derived类型的对象,pd1和pd2是一样的,并且对这两个指针执行Derived类型的任何操作都是安全的;
    如果pb实际指向的是一个Base类型的对象,那么pd1将是一个指向该对象的指针,对它进行Derived类型的操作将是不安全的(如访问m_szName),而pd2将是一个空指针(即0,因为dynamic_cast失败)。
    另外要注意:Base要有虚函数,否则会编译出错;static_cast则没有这个限制。这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object model>)中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。

    另外,dynamic_cast还支持交叉转换(cross cast)。如下代码所示。
    class Base
    {
    public:
        int m_iNum;
        virtual void f(){}
    };
    
    
    
    class Derived1 : public Base
    {
    
    };
    
    class Derived2 : public Base
    {
    
    };
    
    void foo()
    {
        derived1 *pd1 = new Drived1;
    
        pd1->m_iNum = 100;
    
        Derived2 *pd2 = static_cast<Derived2 *>(pd1); //compile error
    
        Derived2 *pd2 = dynamic_cast<Derived2 *>(pd1); //pd2 is NULL
    
        delete pd1;
    }

    在函数foo中,使用static_cast进行转换是不被允许的,将在编译时出错;而使用 dynamic_cast的转换则是允许的,结果是空指针。
     

    reinpreter_cast

     

    用法:reinpreter_cast<type-id> (expression)

     

    说明:type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。



    该运算符的用法比较多。
     

    const_cast

     

    用法:const_cast<type_id> (expression)

     

    说明:该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。



    常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

    Voiatile和const类试。举如下一例:

    class B{
    
    public:
    int m_iNum;
    }
    
    void foo(){
    const B b1;
    b1.m_iNum = 100; //comile error
    B b2 = const_cast<B>(b1);
    b2. m_iNum = 200; //fine
    }


    上面的代码编译时会报错,因为b1是一个常量对象,不能对它进行改变;使用const_cast把它转换成一个常量对象,就可以对它的数据成员任意改变。注意:b1和b2是两个不同的对象。

    展开全文
  • c++ 隐式类型转换

    千次阅读 多人点赞 2018-12-25 17:14:32
    文章目录谈谈c++隐式类型转换列举一些隐式类型转换的例子有时候隐式类型转换并不好explic关键词的用法总结 谈谈c++隐式类型转换 什么是c++隐式类型转换?这是指c++自动将一种类型转换成另一种类型,是编译器的一种...

    谈谈c++隐式类型转换

    • 什么是c++隐式类型转换?这是指c++自动将一种类型转换成另一种类型,是编译器的一种自主行为。
    • 为什么c++需要隐式类型转换?
      1. c++多态的特性,就是通过父类的对象实现对子类的封装,以父类的类型返回之类对象。
      2. c++中使用父类的地方一定可以使用子类代替,这也得益于隐式类型转换。
      3. c++是一种强类型的语言,有着非常严格的类型检查,采用隐式类型转换会使程序员更方便快捷一点。
      4. 但是在享受方便的时候,风险也紧跟其后。

    列举一些隐式类型转换的例子

    int i=3;
    double j = 3.1;
    i+j;//i会被转换成double类型,然后才做加法运算。
    
    class A{};
    class B: public A
    {};//B是子类
    void Fun(A& a);
    B b;
    Fun(b);//使用子类对象代替父类对象是可以的,也是因为隐式类型转换。
    

    有时候隐式类型转换并不好

    class Test
    {
    	public:
    		Test(int i);
    };
    
    Test t1 = 1;//正确,由于强制类型转换,1先被Test构造函数构造成Test对象,然后才被赋值给t1
    Test t2(1);//正确
    
    1. 这种情况有时候很好,如果程序员的本意就是如此,那可以省去好几行代码。
    2. 有时这种情况看起来就不那么好,可能是一个错误,程序员错误的写出了这行代码,但是它却奇迹般的没有导致错误,要是因此产生一个bug,那么将是灾难性的。
    3. 为了更准确的表达程序员的自我意愿,本着不怕多写几行代码的心,就使用c++ explicit关键词
    • 再比如有函数用到Test类
    void fun(Test& t);
    fun(1);//这样调用是没有问题的,隐式类型转换会把1转换成Test的对象。
    

    explic关键词的用法

    class Test
    {
    	public:
    		explicit Test(int i);
    };
    Test t2 = 1;//编译报错
    Test t2(2);//编译没问题
    

    总结

    • 隐式类型转换,是编译器自发的行为,所以安全是第一位。所以呢,我们可以得出一条很重要的结论:
      1. 隐式类型转换是从小到大的转换。在数据类型上表现是少字节数据类型,转换成多字节数据类型,保证数据的完整性;在类上表现,从子类转换成父类,保证类对象功能的正常。
      2. 隐式类型转换往往是安全的,但是它可能产生意想不到的危险。
    • 既然有隐式类型转换,那么肯定就有强制类型转换。既然是强制的,那么我们可以猜测一下几点:
      1. 强制类型转换,往往是不安全的,这点要使用者去把握,去了解这种使用是不是安全。
        2. 强制类型转换又是强大的,只要你能保证做的转换的正确性,那么它就是好用的。
    • 强制类型转换和隐式类型转换,我们不能片面的看待他们是不是安全的。存在即合理,安不安全还是要看程序员自己在使用上是否正确,是否合理。
    展开全文
  • Java数据类型转换

    千次阅读 2016-08-30 20:33:38
    类型A转换类型B,这需要类型B拥有类型A的相关性质,他们之间的转换需要准从一定规则,并不是可以任意转换的,最基本的转换思想:只有同类可转换,低级转高级可自动转换,基本数据类型中高级转低级需要强制转换,...

    Java数据类型转换

    在说明数据类型转换(下简称类型转换)之前,得先说明什么是数据,数据可不仅仅是一个值,而是包括描述数据的种类(数据类型)、值以及基于其类型基础上可进行的操作的集合。从类型A转换到类型B,这需要类型B拥有类型A的相关性质,他们之间的转换需要遵从一定规则,并不是可以任意转换的,最基本的转换思想:只有同类可转换,低级转高级可自动转换,高级转低级需要强制转换。
      所谓的自动转换(也称为隐式转化),就是编译器会自动帮助将低级类型转换成高级类型,而不需要程序员添加相关代码;而强制转换(也称为显示转换)则必须由开发人员添加相关代码进行强制转换,强制转换一般用于基本数据类型和不明类型对象(Java程序中常会有对象丢失类型信息,最常见的就是集合中对象是无类型信息的)强制转化为已知类型(不过需要知道这个对象确实是这个类型或其子类类型,否则会抛异常)。

    class A{}
    class B extends A{}
    A a = new B();//低级转高级,自动转换
    B b = (B)new A();//高级转低级,需强制转换,但是,虽然编译不报错,运行却是会报
    //错,因为高级转低级,引用数据类型中,运行时是要检查对象的真身的,真身不是引用对
    //象的类型或子类型是会抛异常的,因为B的功能可能A不具有,
    //也可以这样想:每个B肯定是一个A,但不是每一个A都是B,所以为了以防万一,运行时要做检查
    //低级高级,在引用对象数据类型中,就是继承链(包括接口的实现)上位于顶端的(父类)
    //是高级的,位于底层的(子类)是低级的;而在基本数据类型则自有规定
    

    转换的场景包括从变量的定义到复制、数值变量的计算到方法的参数传递、基类与派生类间的造型等。而由于数据类型的不同,转换的方式也不尽相同,前一节讲过,Java数据类型分为两种:基本数据类型和引用数据类型(详见:Java 变量数据类型),下面就这两种分别讲述数据类型的转换。

    1.基本数据类型之间的转换

    0.分类:

    Java变量数据类型一节讲过,Java基本数据类型实际上分为两类:数值类型和布尔类型。布尔类型只有boolean,所以boolean不能与其他7种基本类型互相转换,无论是自动转换还是强制转换。
      前面已经说过,只有拥有相同性质的“同类”类型才可以相互转换,显然布尔类型与数值类型不是同一类,因为布尔类型是不能计算的,而像字符类型char,虽是字符类型,但其实现是无符号整型(字符的ASCII码),加减乘除获得的结果还是整型,仍可转换成字符型(不过这个时候需要强制转换)。

    1.“低级高级”以及转换

    Java中规定,数值类型的从低级到高级:byte—>(short/char)—>int—>long—>float—>double。short/char同等级。其实这里的低级高级,也可以粗略看成范围的大小,范围小的低级,范围大的高级。
    低等级到高等级可自动转换,即

    byte b = 1;//默认1其实是int,但是直接赋值这种(右边是直接量,编译期就可以判
    //断,若是变量则是需要运行期判断,所以为以防万一,需要强制转换),编译器只会检查
    //是否越界,比如
    byte b1 = 222;//这个时候编译器会报错:很显然右边值超出byte范围
    long l = 100000000000l;//同样的,这里右边数值大于int范围,后面需要添加l/L
    //这个时候不加l/L,前面用强制转换也不行,因为右边的值是被认为int,而这个值超出了
    //int范围,小于int范围,就是一般的低级到高级自动转换
    float f = b;
    float f1 = 1.23f;//浮点型,默认double,不同于整型,这是高级到低级的转换,数值后面加f/F或进行强制转换
    char c = b;//报错,虽然char比byte高级,但是char是无符号型,不能自动转换
    

    另外,对于基本类型对应的包装类,也是能自动转换的,即:

    Integer i = 12;//这里int自动转换成Integer
    //但也只能对对应的基本类型进行自动转换
    byte b = 12;
    Integer i1 = b;//编译错误,这里就不能套用低级高级,因为是两个系统
    Byte b1 = 12;
    Integer i2 = b1;//同样不行,包装类也是引用类型,之间的转换遵守引用类型转换规则
    

    高等级到低等级,需要强制转换

    int i = 99;
    char c =(int)i;
    //很显然,这种转换是需要牺牲精度的,比如这个时候i =99999;大于char的取值范
    //围,这个时候,c只能取i的低两个字节为值,牺牲了精度
    

    当进行数学运算时,数据类型会自动发生提升到运算符左右之较大者,以此类推。当将最后的运算结果赋值给指定的数值类型时,可能需要进行强制类型转换。

    2.引用类型数据之间的转换

    这里不讨论,通过某种方法进行类型转换的情况,比如,类A有个方法:

    public B toB(){
    	//通过某些操作达到类型A转换成类型B
    	return B;
    }
    //典型的有每一个类都有的toString();方法,尤其特殊的,对于String,任意类
    //型对象 :a +"";即可转换成String
    

    1.分类

    引用数据类型的分类,是通过继承链来分类的,何谓继承链?即:A继承B,B继承C,C继承D……这样就形成了一条链:A->B->C->D……其中,父类相对子类来说是高级的,反之则是低级的,不在一条链上就不是“同类”。另外,要说明一点的,不只是继承,实现接口也同样能形成继承链,其中父接口是其实现类的高级。

    2.引用类型数据转换

    低级到高级自动转换,这一点同基本数据类型是一样的,但是,引用类型不同于基本数据类型,引用类型中是有两个东西的:引用与对象(这两个是不同的),而基本数据类型中的变量标识和值基本上可以看成一个:

    class A{
    	public void walk(){}
    }
    class B extends A{
    	public void run(){}
    }
    A a = new B();//可自动转换,但是这个时候a不能调用run方法(没有对外接口)
    

    a是引用,new B()是对象,这个时候,虽然转换了,但是,new B()还是B类型。Java中每次新建一个对象(不管是通过构造器还是反射、序列化等),这个对象的类型就已经确定了,在Java中我们可以通过继承、向上转型的关系使用父类类型来引用它,这个时候我们是使用功能较弱的类型(高级)引用功能较强的对象(低级),这是可行的。但是将功能较弱的类型强制转功能较强的对象时,就不一定可以行了。
      就像上面的例子,new B()对象还是B类型(从这一方面来看,引用类型转换并没有“转换”),只不过,这个时候引用它的是A类型,在Java变量数据类型一节有提到,Java任何对象都是通过引用来使用的,这个时候new B()这个对象只能通过a来访问,而a被限定为A类型,只有A类型功能,其功能被消弱了。如果这个时候想将对象还原,可以这样:

    B b = (B)a;//这个时候只是新增了一个B类型引用b指向new B()对象,引用a仍然是A类
    //型,没受影响。但b却是可以使用B类型所有功能
    

    高级转换成低级,需要强制转换

    //最开始
    B b = (B)new A();//编译正确,运行抛异常
    Class C extends B{}
    A a1 = new C();
    B b1 = (B)a1;//编译正确,运行正确
    

    父类强制转换成子类并不是总是成功,当引用类型的真实身份是父类本身的类型时,强制类型转换就会产生错误。编译器在编译时只会检查类型之间是否存在继承关系(是否是“同类”)以及上下级关系(是否需要强转),有则通过;而在运行时就会检查它的真实类型,是则通过,否则抛出ClassCastException异常。
      所以在继承中,子类可以自动转型为父类,但是父类强制转换为子类时只有当引用类型真正的身份为子类或子类的子类时才会强制转换成功,否则失败。
      想要更好的理解引用数据类型的转换,可以参考:Java的静态/动态类型。

    展开全文
  • 自动类型转换

    万次阅读 多人点赞 2019-02-01 19:51:57
     在java 程序中,不同的基本类型的值经常需要进行相互类型转换类型转换分为自动类型转换和强制类型转换。布尔类型boolean占有一个字节,由于其本身所代码的特殊含义,boolean类型与其他基本类型不能进行类型的...
  • 类型转换类型转换函数

    千次阅读 2018-02-03 21:31:05
    1、C风格类型转换 c语言比较熟悉,指针类型转换很常见。通过圆括号和标识符组成(type) expression。允许任何类型之间的转换过于粗鲁并且在程序语句中难以识别(主要是人工阅读代码可能难以分辨而已,因为C++...
  • 1、小的类型自动转化为大的类型 2、整数类型可以自动转化为浮点类型,可能会产生舍入误差 3、字符可以自动提升为整数 示例代码: 隐式类型转换 int i = 128; double b = i;//128.0 整数类型可以自动转化为浮点...
  • JS类型转换

    千次阅读 2018-09-25 17:38:57
    1.强制类型转换 强制类型转换指将一个数据类型强制转换成另一种数据类型类型转换主要指将其他的数据类型转换成String Number Boolean。 (1)将其他数据类型转换成String类型 方法一:调用被转换类型的toString()...
  • C语言强制类型转换

    万次阅读 多人点赞 2018-10-12 00:18:44
    强制类型转换是通过类型转换运算来实现的。其一般形式为: (类型...例如: (float) a 把a转换为实型(int)(x+y) 把x+y的结果转换为整型在使用强制转换时应注意以下问题:1.类型说明符和表达式都必须加括号(单个变量...
  • js隐式类型转换

    千次阅读 2019-01-21 10:10:55
    你所忽略的js隐式转换 你有没有在面试中遇到特别奇葩的js隐形转换的面试题,第一反应是怎么会是这样呢?难以自信,js到底是怎么去计算得到结果,你是否有深入去了解其原理呢?下面将深入讲解其实现原理。 其实这篇...
  • SparkSql 数据类型转换

    万次阅读 2019-10-14 08:44:38
    SparkSql 数据类型转换1、SparkSql数据类型1.1数字类型1.2复杂类型2、Spark Sql数据类型和Scala数据类型对比3、Spark Sql数据类型转换案例3.1获取Column类3.2测试数据准备3.3spark入口代码3.4测试默认数据类型3.5把...
  • java类型转换

    千次阅读 2018-07-02 15:27:03
    类型转换Java中的类型转换可以分为13种,1 标识转换 是最简单的就是同种类型之间的转换。2 拓展简单类型转换 拓展简单类型转换涉及到基本数据类型,比如byte转换为short,int,long,float,double;short转换为int,long...
  • 小范围类型-->-->大范围类型:自动类型转换。 2.大范围类型-->-->小范围类型1.若大范围类型的数超出小范围类型的值的范围: 报错,精度会有损失。 2.若大范围类型的数没有超出小范围类型值范围: 1. 若小范围类型...
  • a="12345"; inti; 第一种方法:i=Integer.parseInt(a); 第二种方法:i=Integer.valueOf(a).intValue();
  • 在我们学习c语言的时候,就知道强制类型转换和隐式类型转换,但是在类型转换的过程中,很有可能一个不注意,容易出问题,这无疑是加大了,程序员的工作量,而且还检查很不好检查。 所以在c++ 中就对类型转换做...
  • Scala类型转换

    千次阅读 2019-06-12 09:36:18
    类型隐式转换 自动类型转换说明 object TypeDemo8 { def main(args: Array[String]): Unit = { var n1 = 10 var n2 = 1.1f // float var n3 = n1 + n2 println(n3.isInstanceOf[Float]) } } object...
  • PostgreSQL 数据类型转换类型转换的三种格式
  • C语言数据类型转换

    千次阅读 2020-03-04 09:56:45
    文章目录一、自动类型转换1、操作数中没有浮点型数据时2、操作数中有浮点型数据时3、赋值运算符两侧的类型不一致时4、右值超出左值类型范围时二、强制类型转换三、课后作业四、版权声明 计算机进行算术运算时,要求...
  • 一、JS需要类型转换的原因 JS是一种弱类型语言,变量没有类型限制,可以随意赋值。如: var a=5; console.log(typeof a);//number a='我是字符串'; console.log(typeof a);//string如上所示,当把数字5赋值给a...
  • mysql之类型转换函数

    万次阅读 2019-04-08 14:32:02
    1.隐式类型转换和显式类型转换的概念 隐式类型装换: 两个值进行运算或者比较,首先要求数据类型必须一致。如果发现两个数据类型不一致时就会发生隐式类型转换。例如,把字符串转成数字,或者相反: SELECT 1+‘1’; ...
  • java自动类型转换与强制类型转换

    千次阅读 2018-02-03 16:41:40
    我们知道数据类型有很多种,大小也不一样,就像水桶似的,有1升的,2升的,4升的,自动类型转换就相当于把小的水桶里面的水装到大的里面去。比如  int a = 10;  double b = a;  输出b是10.0;没...
  • JAVA中显式类型转换和隐式类型转换

    千次阅读 2018-07-27 16:00:05
    自动类型转换(隐式类型转换),由系统自动完成的类型转换。从存储范围小的类型到存储范围大的类型。由于实际开发中这样的类型转换很多,所以Java语言在设计时,没有为该操作设计语法,而是由JVM自动完成。 转换...
  • MyBatis 类型转换

    千次阅读 2019-02-19 00:31:10
    MyBatis 类型转换器 每当MyBatis设置参数到PrepareStatement或者从ResultSet结果集中取值时,就会用到TypeHandler来处理数据库类型与Java类型之间的转换。 myBatis类型转换器适用于 Java实体类中的类型和数据库中的...
  • mapstruct 之 类型转换

    万次阅读 2019-09-16 16:31:01
    是不是有时候发现明明source和target不是同一个类型,但是却转换成功了,这是因为mapstruct有一套自己的类型转换机制 类型转换的流程 首先尝试自动进行类型转换 若是无法支持的类型转换,则是尝试调用已经存在的...
  • c++类的类型转换函数

    千次阅读 2017-08-12 12:45:15
    之前学习的,可以将普通类型转换为类类型,需要借助转换构造函数。那么反过来,类类型可以转换为普通类型吗?#include <stdio.h>class TestCls{ public: int a; TestCls(int x = 0) : a(x) {} };int main(void) { ...
  • 【C++】四种强制类型转换

    万次阅读 多人点赞 2019-02-28 21:05:08
    C++ 四种强制类型转换   C语言中的强制类型转换(Type Cast)有显式和隐式两种,显式一般就是直接用小括号强制转换,TYPE b = (TYPE)a; 隐式就是直接 float b = 0.5; int a = b; 这样隐式截断(by the way 这样...
  • Java 类型转换

    万次阅读 多人点赞 2019-05-17 08:11:26
    一、自动类型转换(隐式类型转换) 整型、实型(常量)、字符型数据可以混合运算。不同类型的数据先转化为同类型再进行运算 自动转换按从低级到高级顺序: char ↓ Byte→short→int→long---›float→double ...
  • golang语言强制类型转换

    千次阅读 2020-02-09 20:08:47
    golang是强类型语言,有强制类型转换,但是不同于Java语言所使用的强制类型转换。 golang强制类型转换 golang语言中分为类型转换(type conversion)、类型断言(type assertion)和指针类型转换。 golang的类型断言
  • C语言中的数据类型转换

    千次阅读 多人点赞 2019-01-13 22:02:03
    1.若参与运算量的类型不同,则先转换成同一类型,然后进行运算。 2.转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。 3.所有的浮点运算都是以双精度进行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,485,903
精华内容 994,361
关键字:

类型转换1