1:二进制怎么表示正整数与负整数?
23的原码是010111。反码是010111(正数的反码是它本身)。补码是010111(正数的补码也是它本身)。
-16的原码是110000。反码是101111(负数的反码符号位不变,数值为1变为0,0变为1)。补码是110000(负数的补码位反码+1)。
对于负整数而言,按照“原反码=原码(最高位不变,其余按位取反);补码=反码+1”原则发生变化:
比如-5的存储:
【因为-5表示是:1000 0101(原码)=>1111 1010(反码)=>1111 1011(补码,存储的就是这个)】
2:位(bit),与字节是什么?
3:java的基本的数据类型有哪些?占多少字节?
整型(4个): byte、short、int、long = 1,2,4,8
浮点型(2个):float、double = 4,8
字符(1个): char = ?
布尔类型:(1个): boolean = 1
java中char占用的字节:1、java中内码中的char使用UTF16的方式编码,一个char占用两个字节;2、java中外码中char使用UTF8的方式编码,一个字符占用【1~6】个字节。
在讨论这个问题之前,我们需要先区分unicode和UTF。
unicode :统一的字符编号,仅仅提供字符与编号间映射。符号数量在不断增加,已超百万。详细:[https://zh.wikipedia.org/zh-cn/Unicode]
UTF :unicode转换格式 (unicode transformation format) 。定义unicode中编号的编码方式。utf8和utf16便是其中两种实现方式。其中utf8为变长表示,长度可能时1~6个字节;utf16为变长表示,长度可能是2或4个字节。详细:UTF8 [https://zh.wikipedia.org/zh-cn/UTF-8] UTF16 [https://zh.wikipedia.org/zh-cn/UTF-16]
接着,要分清内码(internal encoding)和外码(external encoding)。
内码 :某种语言运行时,其char和string在内存中的编码方式。
外码 :除了内码,皆是外码。
要注意的是,源代码编译产生的目标代码文件(可执行文件或class文件)中的编码方式属于外码。
先看一下内码
JVM中内码采用UTF16。早期,UTF16采用固定长度2字节的方式编码,两个字节可以表示65536种符号(其实真正能表示要比这个少),足以表示当时unicode中所有字符。但是随着unicode中字符的增加,2个字节无法表示所有的字符,UTF16采用了2字节或4字节的方式来完成编码。Java为应对这种情况,考虑到向前兼容的要求,Java用一对char来表示那些需要4字节的字符。所以,java中的char是占用两个字节,只不过有些字符需要两个char来表示。
外码
Java的class文件采用UTF8来存储字符,也就是说,class中字符占1~6个字节。
Java序列化时,字符也采用UTF8编码,占1~6个字符。
总结:
java中内码(运行内存)中的char使用UTF16的方式编码,一个char占用两个字节,但是某些字符需要两个char来表示。所以,一个字符会占用2个或4个字节。
java中外码中char使用UTF8的方式编码,一个字符占用1~6个字节。
UTF16编码中,英文字符占两个字节;绝大多数汉字(尤其是常用汉字)占用两个字节,个别汉字(在后期加入unicode编码的汉字,一般是极少用到的生僻字)占用四个字节。
UTF8编码中,英文字符占用一个字节;绝大多数汉字占用三个字节,个别汉字占用四个字节。
4:java怎么定义一个局部变量?
局部变量声明在方法、构造方法或者语句块中;
局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
访问修饰符不能用于局部变量;
局部变量只在声明它的方法、构造方法或者语句块中可见;
局部变量是在栈上分配的。
局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
5:java 给变量赋值;
package 类的重载; /* 1、方法的形参的传递机制:值传递 1、形参:方法定义时,声明的小括号内的参数 2、实参:方法调用时,实际传给形参的参数 2、值传递机制: 如果参数是基本数据类型,此时实参赋给形参的是实参真是存储的数据值 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值 (引用型数据包括数组、对象、接口) 3.实例对象与局部变量的差别: 1.实例变量是声明在类内而不是方法中 2.局部变量是声明在方法中 3.局部变量没有默认值,使用前必须先初始化。而实例变量有默认数值,数字(包括char)的预设为0,boolean类型预设是false,对象的引用是null。 PS:方法的参数基本上和局部变量相同 */ public class valueTransfer { public static void main(String[] args) { //交换两个值的操作 int m = 10; int temp = m; int n = 20; valueTransfer test=new valueTransfer(); test.Swap(m,n); System.out.println("2、m:" + m + ",n:" + n); // m=n; // n=temp; // System.out.println("m:"+m+",n:"+n); } public void Swap(int m,int n){ int temp=m; m=n; n=temp; System.out.println("1、m:" + m + ",n:" + n); } }
引用传递
package 类的重载; public class valueTransfer2 { public static void main(String[] args) { Data data = new Data(); data.m = 10; data.n = 20; valueTransfer2 test = new valueTransfer2(); //将对象作为参数传递给方法swap() test.swap(data); System.out.println("2、m:" + data.m + ",n:" + data.n); } public void swap(Data data){ int temp=data.m; data.m=data.n; data.n=temp; System.out.println("1、m:" +data.m + ",n:" +data.n); } } class Data { int m; int n; }
6: int类型赋值给byte, 赋值给long;
byte类型,Java为其分配了一个字节内存,占8位,所有取值范围是:-2^7 ~ 2^7-1 ; 也就是 -128 到 127 ;
int类型,Java为其分配了四个字节内存,占32位,所有取值范围是:-2^31 ~ 2^31-1 ; 也就是 -2147483648 到 2147483647 ;
因为系统有一个自动转换功能,只要赋予byte的值不超过byte的取值范围,系统都会自动帮你转换;
当赋予的值超过了byte类型的取值范围,那就要手动进行数据类型转换了,不然系统程序就报错了;
如: byte test3 = 128 ; //报错:Type mismatch: cannot convert from int to byte
改为:byte test3 = (byte) 128 ; 就可以
其中char、short类型也是一样的,当赋予int类型的值不超过这些类型的取值范围,那系统就会自动进行数据类型转换了;
7: 把double类型强制转化为float赋值给float;
double d = 8.4;
float f = (float)d;
强转可能会产生精度丢失