布尔型 boolean
(能做什么)布尔型数据用来表达现实中的逻辑结果真、假,常常在程序里有程序执行的条件的地方使用
(是什么)true、false
字符型 char
(能做什么)字符型数据具有语言意义上的意义,可以用来表示我们语言和生活中的字符,用来交流
(是什么)字符型数据用单引号括起来 char c = 'a'; 在编译完成后的 class 文件中字符数据使用 Unicode 字符集,所以 java 字符数据是 16 bits,Unicode 代码点机制,而在 java 源码中,myeclipse 一般默认设置的是 utf-8 编码,我们的操作系统一般是 gbk 编码。
数值型 Number
(能做什么)数值型数据用来表达数值的,数值和数学上的数一个意思,一个数值除了是一个符号外,还有数学意义上的可度量的意义
整数
类型
long 类型常量后面加 l 或者 L, long number = 50L
浮点
默认浮点型常数是double 类型
因为相同浮点数可能有不同精度的,浮点数只要经过运算都有可能改变其精度,所以程序中一般不能用“==”来做比较,一般用大于小于来比较(关于 java 中浮点数精度 问题)。
从我们生活意义上看,整数是浮点数的子集;从计算机底层上来看,但是整数和浮点数在内存从的保存形式区别很大,他们的操作方法差别也很大,这就是为什么整数可以进行逻辑运算,而浮点数不行,这块参照计算机原理部分,保留这个区别我想是为了方便 c 程序猿。其实 JVM 很多运算指令把 boolean char byte short 类型的运算都转为 int 类型的运算。
(为什么)引用数据类型和基本数据类型数据,最大区别就是在存储形式上,是否有引用数据的保存,基本数据类型,只有数据内容的保存,引用数据类型,还保存有数据内容的引用
我们把计算机表示的数据分为两部分,一个是数据本身,一个就是数据类型,某种数据可以属于多种数据类型(向上转型),数据类型涉及到数据在计算机中的存储方式和使用方式,引用数据类型和基本数据类型就是从这个角度来分的。但是计算机中所有东西都是数据,数据类型也是数据,所有又专门搞了一种数据类型来描述数据类型这种数据这就是 Type 接口。在 java 里面数据类型这种数据主要可以分为 class interface enum @interface 数组 基本数据类型 6大种,它们都以 Class 这种数据类型存储和使用,class enum @interface 数组 它们都有实例,其实例都是 Ojbect 类型,interface 没有自己类型的实例,但有 class 类型的实例,基本数据类型直接保存数据。
String 类型比较特殊,因为 JVM 中一般是用 c、c++ 写的,它们自身就支持 String 类型数据,而 jvm 基本数据类型中是没有 String 类型的,但是在 JVM 的常量池中,却有 utf-8 类型的结构,用来间接存储字符串,比如类名、函数名、字段名、程序中的字符串常量,间接是因为上述类型不是直接持有 utf-8 结构的索引,而是它们自身对应的结构的索引,它们自身机构中最终会索引到 utf-8 结构上。所以 String 类型的实例通常保存在方法区中的类常量池中,而不是保存在堆中。Class 这种数据类型的实例和 String 也一样,保存在方法区中。
(能做什么)常数(据)是用来给我们向编译器表达数据的方式,人与编译器进行交流时使用的数据形式
根据数据的实际意义常量分为:
要使用字符串来获取某种引用类型,1.使用反射可以实现;2.枚举类型可以实现。
(能做什么)在现实中,事物的属性这种信息在事物的运动发展过程中是变化的,或者是只能在事物发展到某个时刻才能确定这些信息,变量就是用来存储这种信息的对象,并把这种信息保存在内存中,方面我们使用语句来操作这些变量,实现事物运动变化的过程的描述。
(为什么)从底层实现来看,变量是一个在内存中位置确定(是指在程序执行的时候,这个变量要么在 java 栈中,要么在堆中),大小确定的存储单元
(是什么)
和常数据相比较,常量和变量的主要特点是用来存储在程序执行过程中(运行时)才能确定的内容,而不是编译器(编译时)就可以确定的内容。
从上层来看,变量名和人名一个道理,主要是提供对数据操作的方法
变量声明格式: int age;
从实现层面来看,变量的声明提供了变量的大小和存储位置的说明(如果是字段,JVM 通过符号索引来确定它的存储位置,具体见:对象的内存结构),变量的类型,说明了要创建的存储单元的大小,变量的名字,说明了创建的存储单元的存储位置
从抽象层面来看,变量的声明是程序员和计算机之间的通信,是通过计算机提供的接口告诉计算机要创造一个什么样的信息存储单元
(ps:基本类型的变量,是一种最基本 的元对象,其他的对象都是由他们构造的,这里的构造不是继承的关系,是组合的关系。
和动态语言相比,java 这种静态语言在变量声明的时候就指定了变量的大小,动态语言是执行程序的时候根据变量值的类型决定变量的大小,这好比一个人的人名没有类型,但是这个人这个实体对象是有类型的。
和弱类型语言相比,java 这种强类型语言,在使用变量的时候,需要先声明变量的类型。而弱类型语言是编译器根据变量的值自动决定变量的类型,并且变量的值的类型改变时,变量的类型亦自动改变
感觉弱类型和动态语言好像完全一样嘛,只是定义不一样,我靠,被搞晕了!!)
java 里面数据类型转换主要遵循两个原则:同语义转换,语义相同的数据类型之间可以转换,主要是指数值类型之间可以转换;同存储转换,存储方式相同的数据类型之间可以转换,主要是 char 和 整型之间可以转换。引用类型之间,父子类之间可以转换,我觉得这个也应该是同语义原则。
类型转换的时候,涉及到范围问题的,如果 java 编译器能判断没有越界的不会报错,否则会报错。
类型转换检查这种事情是编译器干的事情(这从另一个方面说明使用反射的时候类型检查就不能使用了,这也是为什么使用反射的时候很多对象用 Object 类型),因为 jvm 很多指令不是对所有类型支持,只支持 int float double long 类型,所以 java 编译器本身就要进行类型转换,并且在转换之前进行类型转换安全检查,比如
class HelloWorld { public static void main(String [] args) { short s = 1; System.out.println(s); } }
其中红框中的两行就是 short i = 1; 对应的指令,它们都是对 int 类型数据操作的指令,iconst_1 是从常量池加载一个 int 数据到 jvm 当前函数的 操作数栈, istore_1 是把刚刚入栈的 int 数据弹出操作数栈,并写入到 局部变量区第1索引位置(因为这个 static 函数 args 变量占据了 0 索引位置。),经过 javac 之后局部变量 short s 完全就是 int 类型了。
举个栗子说说 javac 对应类型转换的检测,
short s = 1; 这个表达式里面 1 是默认的整型,那么就是 int 类型了,s 是 short 类型,这样的话,相当于默认给1变为(short)1,这种默认的行为,java 编译器是会检查数据类型转换是否可行的,因为是默认,容易犯错误,而不像显示的强制类型转换,开发者是有意识的使用类型转换,此时 java 编译器对类型转换的要求就没有那么严格。隐式转换的时候,在 java 编译器检查类型类型转换遵循“ java 编译器能判断没有越界的不会报错,否则会报错。”。因为 1 是常数,java 编译器自然可以判定有没有越界。而
short s = s + 1; s + 1 是个变量表达式,必须在程序执行的时候,才知道表达式的值,此时 java 编译器就会报错。short s += 1;这个是个特殊的情况,在这里老毕有一句话解释了,说凡是复合赋值运算符都是带有强制类型转换的,也就是显示的强制类型转换,那么 java 编译器就不会报错了,因为你一旦使用复合运算符,java 编译器认为你是有意识的使用类型转换,为什么java编译器这样设定,我觉得可能是复合赋值运算符本来就是给高手准备的一种简易表达形式,java 编译器把使用者设为高手,自然要限制少一点。
不同长度的带符号的数据之间进行数据转换的方法:
short -> int 把 short 类数据按符号位补齐
int -> short 直接截断高位,所以如果数据超出范围会出现问题
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com