向前引用 ? float VS long ? 这些知识你懂吗?
thinking in java 读书笔记(感悟);
作者:淮左白衣 ;
写于 2018年4月2日18:14:15
目录
基本数据类型
我们常说的基本数据类型是有8种的,但是在thinking in java 里面把void也当做基本数据类型了 ;
| 基本数据类型 | 大小 | 最小值 | 最大值 | 包装器类型 |
|---|---|---|---|---|
| boolean | ——(没有明确指定) | —— | —— | Boolean |
| char | 16 - bit | unicode 0 | unicode 216−1" role="presentation">216−1216−1 | Character |
| byte | 8 - bit | -128 | 127 | Byte |
| short | 16 - bit | −215" role="presentation">−215−215 | 215−1" role="presentation">215−1215−1 | Short |
| int | 32 - bit | −231" role="presentation">−231−231 | 231−1" role="presentation">231−1231−1 | Integer |
| long | 64 - bit | −263" role="presentation">−263−263 | 263−1" role="presentation">263−1263−1 | Long |
| float | 32 - bit | 1.4E−45" role="presentation">1.4E−451.4E−45 | 3.4028235E38" role="presentation">3.4028235E383.4028235E38 | Float |
| double | 64 - bit | 4.9E−324" role="presentation">4.9E−3244.9E−324 | 1.7976931348623157E308" role="presentation">1.7976931348623157E3081.7976931348623157E308 | Double |
| void | —— | —— | —— | Void |
我们可以看到对于boolean类型,是没有明确指定其大小的;仅仅定义为够取其字面值 true 和 false ;
float 和 long 谁更大
我们都知道 float 是 32 位,long 是 64位 ;因此,我们可能会脱口而出,当然 64位的 long 更大了 ;
很好,全错了 ;是 float 更大 ;
现在我讲下,为什么 float 比 long 大 ;
这需要从 long 和 float 在内存中的保存方式说起;对比于float,long 在内存中占64位,每一位可以表示 0 或 1,因此最大有 263" role="presentation">263263 ;
而我们的float ,在内存中并不是向 long 那样存储的,也就是说它不是,把每一个二进制位上的数字连在一起,最后转为十进来表示最后的数值的 ;它在内存中的存储方式如下图:
- float 内存存储图
| 第 一 位 | 二 ~ 九 位 | 十 ~ 三十二 位 |
|---|---|---|
| S(符号位) | E(指数域) | F(小数域) |
这8位指数域,配合上系数,秒杀掉long 的 263" role="presentation">263263 ,是绰绰有余的 ;
System.out.println();
用了这么久的,你真的了解System.out.println();吗?
System
System是 java.lang 包下的一个类;
out
out,是System的一个静态成员对象;类型是PrintStream ;
println()
是out对象的一个方法 ;
向前引用
java消除了向前引用 ;书上,就说了这么一句 ;本着刨根问底的精神,我来讲什么是向前引用 ;
什么是向前引用 ;
向前、引用 ,分开看;就是在一个变量定义之前,引用它 ;这在C++等一些语言中,是不可行的 ;java消除了向前引用的错误,意味着,在java中,这样做是可行的 ;
{
j = 7; // ok
}
int j = 9 ;
{
i = 9 ; // error,不能再同一个代码块中使用向前引用
int i = 6 ;
}
这样的代码是正确的,即使 j 定义在后面 ;(备注:向前引用,不能在 同一个 局部代码块中使用;)但是向前引用,仅限于赋值,也就是我们在向前引用的时候,只能对变量进行赋值,不能进行其他操作 ;
为什么向前引用,不能发生在同一个代码块里面
其实这里也就说出了,为什么java可以向前引用;java能向前引用的可行之处,在于,java加载类的时候的顺序 ;
我们这里不讲具体的加载顺序,我会在后面专门写一篇博客讲; 这里我们需要知道:在一个类加载的时候,类的字段成员是最先加载的,然后才是代码块,最后是方法 ;
{
j = 7; // ok
}
int j = 9 ;
这就是为啥 j = 7 ;是OK的原因;其实在执行代码块的时候,j 已经加载进内存,完成默认初始化了 ;
{
i = 9 ; // error,不能再同一个代码块中使用向前引用
int i = 6 ;
}
当在同一个代码里面的时候,java也是要按照顺序进行加载的,i = 9 ; 这时候 i 还并未加载,因此报错 ;
- 向前引用的一些注意事项
class test {
int method() {return n; }
int m = method();
int n = 1;
}
// Junit测试
{
System.out.println(new test().m);
System.out.println(new test().method());
}
// 分别输出:0 , 1 ;
为什么会这样,m的值为什么不是 1?
这就需要从对象的初始化说起了;
当我们创建一个对象的时候,首先会把类的字段成员,按顺序加载进内存,然后,把这些字段成员放进一张表(符号表)里面,以便向前引用,这些字段成员在符号表里面的值,是默认初始化的,比如上面的m、n,它们在这张表里面的值都是默认初始化的值 0 ;
当所有的字段成员,都加载进符号表里面,然后才开始真正的初始化,也就是程序员为它们赋予的值,比如上面的 m = method()、n = 1 ;
OK,知道上面的知识,就好理解m为什么是 0 ,而不是 1 了 ;当创建 test 对象的时候,默认初始化结束后,开始真正的初始化; m = method() : m 的值是方法 method()的返回值,而 method() 返回的是n的值,这时候,n被真正初始化了吗?答案是否定的,因为下一条语句,才是 int n = 1 ;才进行真正的初始化;因此,n的值,只是在符号表中的默认初始化值 0 ;因此,m 的值,就会赋予为 0 了 ;
向前引用 ? float VS long ? 这些知识你懂吗?的更多相关文章
- Java向前引用容易出错的地方
所谓向前引用,就是在定义类.接口.方法.变量之前使用它们,例如, class MyClass { void method() { System.out.println(myvar); } String ...
- java向前引用
根据看书和看得文章,引出了一个关于"向前引用"的问题: public class InstanceInitTest { static { // { a = 6; System.ou ...
- python自定义函数可以向前引用不用声明
#有些编程语言不够"聪明",向这类向前引用的方式会导致报错,但Python足够"醒目",这段代码是正确的! def next(): print('我在n ...
- wpf staticresource 是不允许向前引用(forward reference)的
不允许向前引用(forward reference)在C/C++中中很常见,即在语法上,未定义变量.类之前,不能使用. 没想到wpf中的wpf staticresource也遵循这种规则.资源字典中, ...
- 引用 字库编码Unicode相关知识
引用 weifeng.shen 的 字库编码Unicode相关知识 1. 各地编码 首先说明一下现在常用的一些编码方案: 1. 在中国,大陆最常用的就是GBK18030编码, ...
- C++学习之路—引用(一)—基础知识
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对一个数据可以建立一个“引用”,它的作用是为一个 ...
- javac之向前引用
可以参考JLS7:https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3 public class Test5 ...
- C++:引用的简单理解
前言:引用是C++一个很重要的特性,最近看了很多有关引用的资料和博客,故在此对引用的相关知识进行总结 一.什么是引用 引用,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作 ...
- 【转】WPF的知识
[-] 闲话WPF之二XAML概述 闲话WPF之五XAML中的类型转换 闲话WPF之十六WPF中的资源 2 闲话WPF之十九WPF中的传递事件 1 闲话WPF之二十WPF中的传递事件 2 闲话WPF之 ...
随机推荐
- jmeter压测过程中报java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider
由于在java中添加了第三方安全策略文件,具体请看https://www.cnblogs.com/mrjade/p/10886378.html,导致在用jmeter压测过程中会遇到以下错误 解决办法: ...
- docker 笔记--运行中的容器如何添加端口映射
解决: iptables -t nat -A DOCKER -p tcp --dport ${YOURPORT_1} -j DNAT --to-destination ${CONTAINERIP}:$ ...
- vue.js 中this.$router.push()的使用
在vue项目中,跳转可以用router-link直接跳到某个页面 因为有时候会需要做一些判断等情况,所以要用到 this.$router.push() 因为外链跳转根本就不在router的设计考虑范围 ...
- Dockerfile 指令 WORKDIR介绍
Dockerfile中的WORKDIR指令用于指定容器的一个目录, 容器启动时执行的命令会在该目录下执行. 相当于设置容器的工作目录了.我们来看一个dockerfile文件 #test FROM ub ...
- elasticsearch java插入索引批量操作
1.单条所以插入//第一个参数:索引名:第二个参数:索引类型:第三个参数:索引ID(相同的id时修改数据,默认为随机字符串)IndexResponse indexResponse = client.p ...
- iOS开发~防止navigation多次push一个页面
在点击push下一个页面时,因为各种原因,点一下cell或按钮没有响应,用户可能就多点几下,这时候会打开好几个一样的页面. 这是因为push后的页面有耗时操作或者刚好push到另一个页面时,另一个页面 ...
- 性能测试工具gperftools使用
https://blog.csdn.net/10km/article/details/83820080 https://blog.51cto.com/wulingdong/2043898 https: ...
- ubuntu16上启用外部管理端口
docker启动外部访问端口在Ubuntu上: [root@maintance systemd] $cd /lib/systemd/system/ [root@maintance system] $c ...
- connections java.net.BindException: Address already in use_解决方案
一.问题描述 在Linux服务器(CentOS7系统)中配置并启动JMeter远程监控服务器资源所需的ServerAgent目录下的 startAgent.sh 文件时,系统出现异常提示,如 [roo ...
- 使用libxml2创建和解析xml文件
毕业设计需要用到xml文件来组织和存放数据, 对于Linux环境下,有libxml2可供使用. 经过一段时间查询文档和网站, 基本掌握创建xml文档和解析xml的操作, 简单做一下记录. 创建xml ...