javajls的简单介绍

博主:adminadmin 2022-12-02 19:15:08 69

本篇文章给大家谈谈javajls,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

javashort怎么-1

注:如未特别说明,Java语言规范 jls 均基于JDK8,使用环境是 eclipse4.5 + win10 + JDK 8

本篇的知识点,主要是涉及到 Java 中一些比较常见的默认窄化处理(Java编译器自动添加的),这里将从一个问题开始,据说这也是一道常见的笔试题/面试题:

为什么 short i = 1; i += 1; 可以正确编译运行而 short i = 1; i = i + 1; 会出现编译错误?

其他说法:都放在一起编译会出现有什么结果,哪一行报错?为什么?

笔者注:其实这其中会涉及到一些编译优化和底层的知识,限于知识面,本篇不涉及,如有需要,可自行搜索。

本文的目录结构如下:

1、结论

关于开篇提出的问题,这里先直接给出结论:

Java语言规范规定基础数据类型运算默认使用32位精度的int类型

只要是对基本类型做窄化处理的,例如 long - int - short - char,都需要做强制转换,有些是Java编译器默认添加的,有的则是代码中显式做强制转换的。

short i = 1; i += 1;可以正确编译运行是因为Java编译器自己添加了强制窄化处理,即对于任何的T a; X b; a += b;等价于T a; X b; a = (T) (a + b);Java编译器会默认做这个显式强制转换(尽管有时候会出现精度问题,例如 b 是 float 、 double 类型,强烈建议不要有这样的操作)。前面的i += 1其实就等价于i = (int) (i + 1),即便将数字1换成是double类型的1.0D也是如此。

short i = 1; i = i + 1;编译不通过的原因就很明显了:无论是代码中,还是Java编译器,都没有做强制转换,int 类型直接赋给 short ,因此编译出错。

对于常量(数字常量、常量表达式、final常量等),Java编译器同样也可以做默认的强制类型转换,只要常量在对应的数据范围内即可。

2、详解

接下来讲详细分析为什么 short i = 1; i += 1; 可以正确编译而 short i = 1; i = i + 1; 则会编译失败。先列一下搜出来的一些令人眼前一亮(or 困惑)的代码

public static voidmain(String[] args) {//注:short ∈ [-32768, 32767]

{/** 1、对于 +=, -=, *=, /=, Java编译器默认会添加强制类型转换,

* 即 T a; X b; a += b; 等价于 T a; X b; a = (T) (a + b);*/

//0是int类型的常量,且在short范围内,被Java编译器默认强制转换的

short i = 0;

i+= 1; //等价于 i = (short) (i + 1);

System.out.println("[xin01] i=" + i); //输出结果: 1

i = (short) (i + 1);

System.out.println("[xin02] i=" + i); //输出结果: 2

/** 下面这2行都会有编译报错提示:

* Exception in thread "main" java.lang.Error: Unresolved compilation problem:

* Type mismatch: cannot convert from int to short

* [注]错误: 不兼容的类型: 从int转换到short可能会有损失

* Eclipse 也会有提示: Type mismatch: cannot convert from int to short*/

//i = i + 1;//i = 32768;

i= 0;

i+= 32768; //等价于 i = (short) (i + 32768); 下同

System.out.println("[xin03] i=" + i); //输出结果: -32768

i += -32768;

System.out.println("[xin04] i=" + i); //输出结果: 0

i= 0;long j = 32768;

i+=j;

System.out.println("[xin05] i=" + i); //输出结果: -32768

i= 0;float f = 1.23F;

i+=f;

System.out.println("[xin06] i=" + i); //(小数位截断)输出结果: 1

i= 0;double d = 4.56D;

i+=d;

System.out.println("[xin07] i=" + i); //(小数位截断)输出结果: 4

i= 10;

i*= 3.14D;

System.out.println("[xin08] i=" + i); //输出结果: 31

i= 100;

i/= 2.5D;

System.out.println("[xin09] i=" + i); //输出结果: 40

}

{/** 2、常量表达式和编译器优化: 常量折叠*/

//2 * 16383 = 32766//(-2) * 16384 = -32768//都在 short 范围内,常量表达式在编译优化后直接用对应的常量结果,然后编译器做强制转换

short i = 2 * 16383; //等价于 short i = (short) (2 * 16383);

short j = (-2) * 16384;//2 * 16384 = 32768,超过 short 范围,编译器不会做转换//Type mismatch: cannot convert from int to short//short k = 2 * 16384;//常量表达式在编译优化后直接用对应的常量结果,然后编译器做强制转换

short cThirty = 3 * 10;short three = 3;short ten = 10;//Type mismatch: cannot convert from int to short//short thirty = three * ten;

final short fTthree = 3;final short fTen = 10;//常量表达式在编译优化后直接用对应的常量结果,然后编译器做强制转换

short fThirty = fTthree *fTen;final short a = 16384;final short b = 16383;//常量表达式在编译优化后直接用对应的常量结果,然后编译器做强制转换

short c = a +b;

}

}

接下来根据代码罗列的两部分分别进行说明:

2.1、对于 +=, -=, *=, /=, Java编译器默认会添加强制类型转换,即 T a; X b; a += b; 等价于 T a; X b; a = (T) (a + b);

A compound assignment expression of the formE1 op= E2is equivalent toE1 = (T) ((E1) op (E2)), whereTis the type ofE1, except thatE1is evaluated only once.

For example, the following code is correct:

short x = 3;

x+= 4.6;

and results in x having the value 7 because it is equivalent to:

short x = 3;

x= (short)(x + 4.6);

笔者注:

实际上,直接加上强制类型转换的写法,也是大家都熟悉且理解起来最清晰的方式,可以避免可能潜在的类型不匹配时出现的精度损失问题,使用的时候需要注意。当然,笔者认为这些方式都没有好坏之分,正确地使用即可。

Java从语言规范层面对此做了限制。有兴趣的还可以通过 class文件和 javap -c 反汇编对所使用的字节码作进一步的研究。

知道了Java语言相关的规范约定,我们就可以看出,与之对应的是以下这种出现编译错误的写法(报错提示:Type mismatch: cannot convert from int to short):

short i = 1;//i + 1 是 int 类型,需要强制向下类型转换

i = i + 1;

2.2、常量表达式和编译器优化: 常量折叠

需要注意的是,前面的示例short x = 3;中的3其实默认是 int 类型,但是却可以赋值给short类型的x。这里涉及到到的其实是 常量表达式。

In addition, if the expression is a constant expression (

A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.

A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:

Byte and the value of the constant expression is representable in the type byte.

Short and the value of the constant expression is representable in the type short.

Character and the value of the constant expression is representable in the type char.

对于常量表达式,其结果是可以自动做窄化处理的,只要是在对应的数据类型范围内,Java编译器就进行做默认强制类型转换。

Some expressions have a value that can be determined at compile time. These are constant expressions (

true(short)(1*2*3*4*5*6)

Integer.MAX_VALUE/ 2

2.0 *Math.PI"The integer " + Long.MAX_VALUE + " is mighty big."

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (

通过常量表达式赋值的final变量都是常量,这种也是编译期可以确认最终值,会通过编译优化直接赋予最终值,而且可以直接依靠编译器做窄化处理。

对于这一块,其实对应的是一个比较基础的编译器优化:常量折叠(Constant Folding),有兴趣的可以自行搜索。stackoverflow 上由相关的讨论,参考[9]、[10]、[11]

笔者注:

尽管常量表达式最终都被编译器优化为直接值,但是为了清晰,提高可读性、可维护性,代码中没必要对常量直接换算,例如一天 24 * 60 * 60 秒,其实可以分别用可读性更强的final常量来表示。

Bloch大神的 Java Puzzlers 中也有相关的一些说明,有兴趣的可以去看看

Java的基本格式

基本格式:修饰符 class 类名(程序代码)

意义:Java中的程序代码都必须放在一个类中,对于类初学者可以简单地把它理解为一个java程序;类需要使用class作为关键字定义;而在class的前面可以有一些修饰符。

扩展资料

编写java时,特别需要注意的几个书写格式常见的错误:

1.java中的程序代码中功能执行语句的最后都必须用(;)结束。

这里需要注意的是,在程序中不要将英文的分号(;)误写成中文的分号(;) ,如果写成了中文的分号,编译器会报告“Invalid character”(无效字符)这样的错误信息。

2.Java语言是严格区分大小写的。在定义类时,不能将class写成Class,否则编译会报错。程序中定义一个computer的同时,还可以定义一个Computer,computer和Computer是两个全完不同的符号,在使用的时候需要注意。

3. 在编写java代码的时候为了便于阅读,通常会使用一种良好的格式进行排版,但这并不是必须的,我们也可以在两个单词或者符号之间任意换行。

参考资料:百度百科-java

java中字节数组与字符数组用法有什么区别

额 最基本的区别就是一个存储字节一个存储字符啊

所以你只要搞清楚字节和字符的区别就好了

字节(Byte):字节是通过网络传输信息(或在硬盘或内存中存储信息)的单位。字节是计算机信息技术用于计量存储容量和传输容量的一种计量单位,1个字节等于8位二进制,它是一个8位的二进制数,是一个很具体的存储空间。

字符:人们使用的记号,抽象意义上的一个符号。 '1', '中', 'a', '$', '¥', ……一个字符(1char = 2byte = 16bit)

详情可以自己百度一下 字节和字符的区别

学习java语言基础哪种书好,

java的内容比C简单多了,去除了很多C/C++中容易出错的地方,如指针等,减轻学习负担,所以有C的基础能很快就能学会(不过C中没有类的概念,C++中有,有C++的基础更容易上手点)。

java的核心在于类,所有的东西都封装在类中,包括main函数,因此建议把类学好。

介绍几本java的书:

java语言程序设计(基础篇、进阶篇)。java的书没什么太经典的,如果要基础的书,我认为这2本还是比较合适的,也足够了。

java编程思想。这本书比较经典,但是最好能有最基本的基础后再来看这本书。java的重点在于类,把类学好,重载、继承等等,学扎实了,后面才有提高。这本书基本上将java的原理讲的很透彻。

java官方API文档。没有比这更好的资料了,官方文档,详细介绍了java官方提供的所有类、接口、方法。不论学什么语言,要想深入及提高,就必须去看官方文档。不过官方文档更多的在于应用,没什么原理。建议用到什么,查什么。

java比其他语言更简单,因此更容易制作很多高效的软件工程工具,如单元测试、重构等,有了扎实的基础,去学习一下这些东西可以提高编程的水平、效率和质量。

设计模式,非常经典,但非常抽象。不过要想在面向对象语言上编程有所提高,这是必备的。而且学了这个你会发现与C这种面向过程的语言的明显不同。

《设计模式》(人称GOF) 、《head first设计模式》

重构,有人说重构是现代软件的面包和水,几乎天天用到,看似感觉不到重要性,但又十分重要。重构主要是调整程序的结构,使得软件更容易面对变化。《重构:改善既有代码的设计》

单元测试工具Junit、UML工具等,很有必要去学。

编程其实没有难度,特别是java这种简单的语言,非常容易上手。去学习设计模式等这些东西我认为更有用些,当然前提是有扎实的基础。

JAVA 读文件一定得创建byte数组????为什么?

看情况吧...

当然你心情好了可以一个字节一个字节的读;

为什么要用byte,其实java读写文件调用的依然是底层操作系统的接口.

在操作系统层面数据时按照块来读的.

申请byte数组的目的是在jvm中开辟一块空间,然后调用jvm操作指令,jvm根据指令告诉操作系统,把这块数据给我填满.操作系统填满之后,java就返回了.

为什么要用byte?因为byte是数据存储的最小单位了.

所以byte[]数组就是一次性读取多少个最小单位,然后返回.

这只是简单的描述,要更详细的了解,建议读java language specification (jls),jls3好像是1.5,1.6的jls7是jdk1.7的.还有就是操作系统原理相关的书.

只能回答这么多了,再深的我也不懂~

关于javajls和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

The End

发布于:2022-12-02,除非注明,否则均为首码项目网原创文章,转载请注明出处。