1.Java语言是跨平台的,请问是如何保证的呢?
因为它有虚拟机(JVM),JAVA程序不是直接在电脑上运行的,是在虚拟机上进行的,每个系统平
台都是有自己的虚拟机(JVM),所以JAVA语言能跨平台。.
2.JDK,JRE,JVM的作用及关系?
JVM:英文全称,Java Virtual Machine,是Java虚拟机,用来运行Java程序
JRE:英文全称,Java Runtime Environment,是Java运行时环境,里边包含了Java运行时所需要的类库。
JDK:英文全称,Java Development Kit,是Java开发工具包,里边包含了Java的开发工具。例如java,javac等。
JDK:JRE+java开发工具
JRE:JVM+类库(lib)
①SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。
②EE(J2EE),enterprise edition,企业版,使用这种JDK开发J2EE应用程序,从JDK 5.0开始,改名为Java EE。
③ME(J2ME),micro edition,主要用于移动设备、嵌入式设备上的java应用程序,从JDK 5.0开始,改名为Java ME。
3.进制转换
(1)其他进制到十进制
系数:就是每一个位上的数值
基数:x进制的基数就是x
权:对每一个位上的数据,从右,并且从0开始编号,对应的编号就是该数据的权。
结果:系数*基数^权次幂之和。
(2)十进制到其他进制
除基取余,直到商为0,余数反转。
另外:2<<3 ==2*2^3
4.数据类型转换
(1)boolean类型不参与转换
(2)默认转换
A:从小到大
B:byte,short,char -- int -- long -- float -- double
C:byte,short,char之间不相互转换,直接转成int类型参与运算。
(3)强制转换
A:从大到小
B:可能会有精度的损失,一般不建议这样使用。
C:格式:
目标数据类型 变量名 = (目标数据类型) (被转换的数据);
(4)思考题和面试题:
1:下面两种方式有区别吗?
float f1 = 12.345f;
float f2 = (float)12.345;
前者12.345本身是一个float类型的数据,而后者12.345是个double类型的,经过强制转换赋值给f2
2:下面的程序有问题吗,如果有,在哪里呢?
byte b1 = 3;
byte b2 = 4;
byte b3 = b1 + b2;
byte b4 = 3 + 4;
第三行有问题,因为可能存在精度损失的情况。
3:下面的操作结果是什么呢?
byte b = (byte)130;//-126
* 分析过程: 我们要想知道结果是什么,就应该知道是如何进行计算的。 而我们又知道计算机中数据的运算都是补码进行的。
而要得到补码,首先要计算出数据的二进制。
*
* A:获取130这个数据的二进制。 00000000 00000000 00000000 10000010 这是130的原码,也是反码,还是补码。
* B:做截取操作,截成byte类型的了。 10000010 这个结果是补码。
* C:已知补码求原码。 符号位 数值位 补码: 1 0000010
* 反码: 1 0000001
* 原码: 1 1111110
D:字符参与运算
是查找ASCII里面的值
'a' 97
'A' 65
'0' 48
System.out.println('a');
System.out.println('a' + 1);
E:字符串参与运算
这里其实是字符串的连接
System.out.println("hello"+'a'+1);
System.out.println('a'+1+"hello");
System.out.println("5+5="+5+5);
System.out.println(5+5+"=5+5");
5.switch语句的表达式可以是byte吗?可以是long吗?可以是String吗?
switch语句的表达式可以是byte,可以是long,jdk1.7之后可以是String。
6.for和while的区别?
a:使用上的区别
for语句的那个控制条件变量,在循环结束后不能在使用了。
而while的可以继续使用。
b:理解上的区别
for适合于一个范围的判断
while适合次数不明确的
举例:吃葡萄
7.Java的内存分配
1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.
2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
3. 堆:存放所有new出来的对象。
4. 静态域:存放静态成员(static定义的)
5. 常量池:存放字符串常量和基本类型常量(public static final)。
6. 非RAM存储:硬盘等永久存储空间
8:栈内存和堆内存的区别:?
栈:数据使用完,会被垃圾回收器在空闲的时候回收。
堆:每一个new出来的东西都有地址, 每一个变量都有默认值
byte,short,int,long 默认 0
float,double 默认0.0
char 默认'\u0000'
boolean 默认 false
引用类型 默认null
常量池中维护的常量仅仅是【-128至127】而String型是先检测常量池中有没有对应字符串,如果有,则取出来;
如果没有,则把当前的添加进去。
9.Java程序的开发,设计和特征?
A:开发:就是不断的创建对象,通过对象调用功能
B:设计:就是管理和维护对象间的关系
C:特征:a:封装 b:继承 c:多态 (d:抽象)
10.成员变量和局部变量的区别?
(1)在类中的位置不同
成员变量:类中方法外,用来描述类。
局部变量:方法定义中或者方法声明上
(2)在内存中的位置不同
成员变量:在堆中
局部变量:在栈中
(3)生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
(4)初始化值不同
成员变量:有默认值
局部变量:没有默认值,必须定义,赋值,然后才能使用
11.构造方法中可不可以有return语句呢?
可以。而是我们写成这个样子就OK了:return;
其实,在任何的void类型的方法的最后你都可以写上:return,代表方法结束;
12.Override和Overload的区别?Overload是否可以改变返回值类型?
a.Overload是指重载,在同一个类中,存在方法名相同,参数列表不同的方法。
重载与返回值类型无关。Overload的方法可以改变返回值的类型,因为它与返回值类型无关。
b. Override是指重写, 存在于子父类,或者子父接口中,方法声明相同
13.this和super的区别和各自的作用?
属性的区别:this访问本类中的属性,如果本类没有此属性则从父类中继续查找。super访问父类中的属性。
方法的区别:this访问本类中的方法,如果本类没有此方法则从父类中继续查找。super访问父类中的方法。
构造的区别:this调用本类构造,必须放在构造方法的首行。super调用父类构造,必须放在子类构造方法首行。
其他区别:this表示当前对象。super不能表示父类对象
14.一个类的初始化过程
加载:由类加载器执行,查找字节码并从字节码创建一个class对象。
链接:在链接阶段将验证类中的字节码,为静态区域分配存储空间,并且如果必须的话,将解析这个类创建的对其他类的所有引用
初始化:首先初始化静态代码块、静态变量、静态方法,如果该类有超类,则对其初始化执行顺序:
静态代码块 > 构造代码块 > 构造方法
15.final关键字
(1)finall是最终的意思,可以修饰类,方法,变量。
(2)特点:
A:它修饰的类,不能被继承。
B:它修饰的方法,不能被重写。
C:它修饰的变量,是一个常量。
16.抽象类的特点
A:抽象类和抽象方法必须用关键字abstract修饰
B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
C:抽象类不能实例化
D:抽象类的子类
a:是一个抽象类。
b:是一个具体类。这个类必须重写抽象类中的所有抽象方法。
16.1 abstract不能和哪些关键字共存
a:final 冲突
b:private 冲突
c:static 无意义
17.抽象类和接口的区别?
A:成员区别
抽象类:有变量,有常量,有构造方法,有抽象方法,可以有非抽象方法
接口:成员变量只能是常量,默认public static final修饰,没有构造方法,成员方法只能是抽象方法默认修饰符:public abstract
B:关系区别:
类与类:继承
类与接口:实现
接口与接口:继承
C:设计理念不同
抽象类:is a,抽象类中定义的是共性功能。
接口:like a,接口中定义的是扩展功能。
18.权限修饰符(四种权限修饰符在任意时刻只能出现一种)
本类 同一个包下 不同包下的子类 不同包下的无关类
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
19.内部类
A:可以直接访问外部类的成员,包括私有
B:外部类要想访问内部类成员,必须创建对象
C:局部内部类访问局部变量必须加final修饰。
因为局部变量使用完毕就消失,而堆内存的数据并不会立即消失。
所以,堆内存还是用该变量,而改变量已经没有了。
为了让该值还存在,就加final修饰。
通过反编译工具我们看到了,加入final后,堆内存直接存储的是值,而不是变量名。
20.static关键字
a.静态方法只能访问静态成员,非静态成员可以访问静态成员或者非静态成员。
b.非静态内部类中不允许定义静态成员
c.外部类的静态成员不可以直接使用非静态内部类
d.静态内部类,不能访问外部类的实例成员,只能访问外部类的静态成员
21.==和equals()的区别?
A:==
基本类型:比较的是值是否相同
引用类型:比较的是地址值是否相同
B:equals()
只能比较引用类型。默认情况下,比较的是地址值是否相同。
但是,我们可以根据自己的需要重写该方法。
22.String和StringBuffer相互转换
String -->StringBuffer
String s = new String();
方法1: StringBuffer sb2 = new StringBuffer();
sb2.append(s);
方法2: StringBuffer sb2 = new StringBuffer(s);
StringBuffer --> String
方法1 toString()方法:
String str2 = buffer.toString();
方法2 通过构造方法:
String str = new String(buffer);//public String(String original)创建的字符串是该参数字符串的副本
23.String,StringBuffer,StringBuilder的区别
String内容不可变;StringBuffer同步的,数据安全,效率低;StringBuilder:不同步的,数据不安全,效率高。
24.B:StringBuffer和数组的区别?
二者都是可以看成一个容器装数据,StringBuffer最终数据是一个字符串,而数组可以放多种数据,但必须是同一个类型。
25.String和int的相互转换
A:String -- int
String s = "100";
// 方式1
// String -- Integer -- int
Integer ii = new Integer(s);
// public int intValue()
int x = ii.intValue();
System.out.println("x:" + x);
//方式2
//public static int parseInt(String s)
int y = Integer.parseInt(s); //这个方法最好
System.out.println("y:"+y);
B:int -- String
// 方式1
String s1 = "" + number;
System.out.println("s1:" + s1);
// 方式2
String s2 = String.valueOf(number); //这个方法最好
System.out.println("s2:" + s2);
// 方式3
// int -- Integer -- String
Integer i = new Integer(number);
String s3 = i.toString();
System.out.println("s3:" + s3);
// 方式4
// publuc static String toString(int i)
String s4 = Integer.toString(number);
System.out.println("s4:" + s4);
System.out.println("-----------------");
今天总结到这,day1-15.
补充
26. ++/--使用?
**单独使用
放在操作数据的前面和后面效果一样。
a++或者++a效果一样。
**参与操作使用
放在操作数的前面:先自增或者自减,再参与操作
int a = 10;
int b = ++a;
放在操作数的后面:先参与操作,再自增或者自减
int a = 10;
int b = a++;
27.+ 以及+=区别?
1) short s1 = 1; s1 = s1+1;有什么错?// s1 = (short) (s1+1);系统提示要强制转换
2) short s1 = 1; s1 += 1;有错吗?//没错,由于+=是强制转换的。。
+:在编译器将右边的表达式结果计算出来后,和左边的变量类型比较精度,如果左边的变量精度低于右边的结果的精度,编译器会显式的报错,告诉程序员去强制转型。(所以s1 = s1 + 1出错)最后将表达式的结果复制到变量所在的内存区。
+=:编译器自动隐式直接将+=运算符后面的操作数强制装换为前面变量的类型,然后在变量所在的内存区上直接根据右边的操作数修改左边变量内存存储的二进制数值(所以 s += 1不报错)最后达到和赋值运算符相同的目的。与前者相比,由于后者是位操作,效率也较前者高。
28. Java中的参数传递问题?
在Java中只有值传递。
基本类型:形式参数的改变不影响实际参数
引用类型:形式参数的改变直接影响实际参数
29.一个类的初始化过程
加载:由类加载器执行,查找字节码并从字节码创建一个class对象。
链接:在链接阶段将验证类中的字节码,为静态区域分配存储空间,并且如果必须的话,将解析这个类创建的对其他类的所有引用
初始化:首先初始化静态块、静态变量、静态方法,如果该类有超类,则对其初始化
30.子父类的构造执行过程
执行父类的静态代码块。
执行子类的静态代码块。
执行父类的构造代码块。
执行父类的不带参数的构造方法。
执行子类的构造代码块。
执行子类的不带参数的构造方法。
分层初始化
1.父类静态代码块 ( java虚拟机加载类时,就会执行该块代码,故只执行一次)
2 .子类静态代码块 ( java虚拟机加载类时,就会执行该块代码,故只执行一次)
3. 父类属性对象初始化
4.父类普通代码块(每次new,每次执行 )
5. 父类构造函数(每次new,每次执行)
6.子 类 属性对象初始化
7.子类普通代码块(每次new,每次执行 )
8.子 类构造函数(每次new,每次执行)
31.字符串的面试题(看程序写结果)
A:==和equals()
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);// false //同样是new出来的对象,在堆里的地址不一样 false
System.out.println(s1.equals(s2));// true //由于两个对象的内容一样,最终指向方法区常量池的地址是一样的true
String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3 == s4);// false S3在堆内存中的地址和s4在常量池的地址不一样
System.out.println(s3.equals(s4));// true S3在堆内存中指向常量池hello,s4直接指向常量池的hello
String s5 = "hello";
String s6 = "hello";
System.out.println(s5 == s6);// true 地址一样
System.out.println(s5.equals(s6));// true 地址一样
B:字符串的拼接
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
System.out.println(s3 == s1 + s2);// false 地址值的比较不一样
System.out.println(s3.equals((s1 + s2)));// true
值得注意的是:字符串如果是变量相加,先开空间在拼接,如果是常量相加,先加,再去常量池找
有就返回,没有就创建一个返回,如下
System.out.println(s3 == "hello" + "world");// false 这里我判断错了,实际上常量相加,结果应该是true
System.out.println(s3.equals("hello" + "world"));// true
32.关于==和equals的问题
33.拆箱he装箱
当数值超出-128~127之外,会false