JavaSE基础
1.访问修饰符public,private,protected以及不写(默认)的区别?
修饰符 | 当前类 | 同包 | 子类 | 其他包 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
2.JAVA中的几种基本类型,各占用多少字节?
下图单位是bit,非字节 1B=8bit
数据类型 | 大小 | 范围 | 默认值 |
byte(字节) | 8 | -128~127 | 0 |
short(短整型) | 16 | -32768~32768 | 0 |
int(整型) | 32 | -2147483648~2147483648 | 0 |
long(长整型) | 64 | -9233372036854477808~9233372036854477808 | 0 |
float(浮点型) | 32 | -3.40292347E+38~3.40292347E+38 | 0.0f |
double(双精度) | 64 | -1.79769313486231570E+308~1.79769313486231570E+308 | 0.0d |
char(字符型) | 16 | '\u000~u\ffff' | '\u0000' |
boolean(布尔型) | 1 | true/false | false |
3.float f = 3.4;这个表达式是否正确?
不正确。在Java里面,没有小数点的默认是int类型,有小数点的默认是double类型。因此3.4是双精度数,将双精度浮(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化),会造成精度损失,因此需要强制类型转换 float f = (float)3.4 或者写成 float f = 3.4f 。
4.short s1 = 1; s1 = s1 + 1; 这个表达式有错吗?short s1 = 1; s1 += 1; 这个表达式有错吗?
前面这个表达式,由于1是int类型,因此 s1 + 1 的运算结果也是int类型,再把int类型的结果赋值给short类型的s1是会报错的,需要对结果进行强制类型转换才能通过编译。后面这个表达式, s1 += 1; 相当于 s1 = (short)(s1 + 1); 表达式,其中会有隐含的强制类型转换,可以正常通过编译。
5.int和Integer有什么区别?
Java是一个近乎纯洁的面向对象编程的语言,但是为了编程的方便还是引入了基本数据类型。为了能够将这些基本数据类型当作对象操作,Java为每一个基本数据类型都引入了相应的包装类型(Wrapper Class),int类型的包装类型就是Integer。从Java5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
Java为每个原始类型(基本数据类型)提供了相应的包装类型:
原始类型:byte,short,int,long,float,double,char,boolean
包装类型:Byte,Short,Integer,Long,Float,Double,Character,Boolean
Integer a = new Integer(3);
Integer b = 3;//将3自动装箱成Integer类型
int c = 3;
System.out.println(a == b);//false 两个引用没有引用同一对象
System.out.println(a == c);//true a自动拆箱成int类型再和c比较
下面这段代码也和自动装箱/拆箱有关系:
Integer f1 = 100, f2 = 100, f3 = 128, f4 = 128;
System.out.println(f1 == f2); // true
System.out.println(f3 == f4); // false
为什么第一个运算的结果是true,第二个却是false呢?
首先注意,f1、f2、f3和f4都是Integer对象引用,所以下面的==运算比较的不是值而是引用。
装箱的本质是什么呢?是当我们给一个Integer对象赋一个int类型值的时候,会调用Integer类的静态方法valueOf(),看看valueOf()方法的源代码就知道为什么会产生这样的结果。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
IntegerCache是Interger类的内部类,其代码如下:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
简单得说,如果整型字面量的值的范围在-128到127之间,那么就不会new一个新的Integer对象,而是直接引用常量池中的Integer对象。
6.&和&&的区别?
&运算符有两种用法,一是按位与,二是逻辑与。&&运算符是短路与。
逻辑与跟短语与的差别是非常大的,虽然二者都要求运算符左右两边的布尔值都是true整个表达式的值才是true,但是如果&&运算符左边的表达式是false的话,右边的表达式会直接被短路掉,不会进行运算,这就是&&运算符被称为短路运算的原因。
很多时候我们需要用到的可能都是&&而不是&,例如在验证用户登录的时候,判定用户名不是null而且不是空字符串,应当写为:userName != null && !userName.equals(""),二者的顺序不能交换,更不能使用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。
7.Math.round(11.5)等于多少?Math.round(-11.5)等于多少?
Math.round(11.5)的结果是12,Math.round(-11.5)的结果是-11。
四舍五入的原理是在参数上加0.5,然后进行向下取整。
那么Math.round(11.6)和Math.round(-11.6)的结果又是什么呢?
答案是12和-12。
11.6 + 0.5 = 12.1,然后向下取整为12;
-11.6 + 0.5 = -11.1,然后向下取整为-12。
要特别理解向下取整是什么意思。
上一篇: C++: 默认参数和内联函数(inline function)
下一篇: javase基础