声明:转载自职业侠公众号(itzhiyexia)#
原文地址:https://gitlab.com/harvic/itguidedata
二、语言基础 课件
语言的偏向性:公司笔试一般都会有C++笔试题和JAVA笔试题两套,如果没有学过C+++或者JAVA,那校招笔试是要吃亏的
2.1 基本数据类型
2.1.1 基础讲解
基本数据类型分为原始类型和包装类型,Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
8种原始类型 | 容量 | 对应包装类型 |
---|---|---|
byte(字节) | 8 位 | Byte |
shot(短整型) | 16位 | Short |
int(整型) | 32 位 | Integer |
long(长整型) | 64 位 | Long |
float(浮点型) | 32 位 | Float |
double(双精度) | 64 位 | Double |
char(字符型) | 16 位 | Character |
boolean(布尔型) | 1 位 | Boolean |
注意几点:
1、各数据类型按容量大小(表数范围大小)由小到大排列为:
byte <—— short, char <——int <——long <——float <——double
2、基本类型之间的转换原则:
1)运算时,容量小的类型自动转换为容量大的类型;
2)容量大的类型转换为容量小的类型时,要加强制转换符,且精度可能丢失;
如:float f = 1.2f;
int ff = (int) f;
System.out.println(ff);
3)short,char之间不会互相转换(需要强制转换),byte、short、char并且三者在计算时首先转换为int类型;
4)实数常量默认为double类型, 整数常量默认为int类型;
3、包装类及String类都是定定义为public final class的,因此这几个都不能被继承;
4、原始类型是可以通过==直接判断是否相等的,而包装类型是类,通过==判断值是否相等是不对的,必须通过equals()函数
**下面的程序中,temp的最终值是什么? **
long temp=(int)3.9;
temp%=2;
A .0
B .1
C .2
D .3
E .4
short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
**下面哪个不是JAVA关键字 **
A integer
B double
C float
D default
2.1.2 历年考题
下面哪些不是java的简单数据类型?
A. short B. Boolean C. Double D. float
0.6332的数据类型是()
A float B double C Float D Double
float f=3.4;是否正确?
下面哪些类可以被继承
下面哪些类可以被继承? Java.lang.Thread、java.lang.Number、java.lang.Double、java.lang.Math、 java.lang.ClassLoader
A、Thread B、Number C、Double D、Math E、ClassLoader
String 是最基本的数据类型吗?
int和Integer有什么区别?
5、请写出下面程序的运行结果:
class AutoUnboxingTest {
public static void main(String[] args) {
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比较
}
}
2.2 String、StringBuilder、StringBuffer
2.2.1 String
字符串常量,不可更改,因为其内部定义的是一个final类型的数组来保存值的,如下:
private final char value[];
所以,当我们每次去“更改”String变量的值的时候(包括重新赋值或者使用String内部的一些方法),其实是重新新建了一个String对象(new String)来保存新的值,然后让我们的变量指向新的对象。因此,当我们需要频繁改变字符串的时候,使用String会带来较大的开销。
定义String的方法有两种:
(1)String str = "abc";
(2)String str2 = new String("def");
第一种方式创建的String对象“abc”是存放在字符串常量池中,创建过程是,首先在字符串常量池中查找有没有"abc"对象,如果有则将str直接指向它,如果没有就在字符串常量池中创建出来“abc”,然后在将str指向它。当有另一个String变量被赋值为abc时,直接将字符串常量池中的地址给它。如下:
String a = "abc";
String b = "abc";
System.out.println(a == b); //打印 true
也就是说通过第一种方式创建的字符串在字符串常量池中,是可共享的。同时,也是不可更改的,体现在:
String a = "abc";
String b = "abc";
b = b + "def";
此时,字符串常量池中存在了两个对象“abc”和“abcdef”。
第二种创建方式其实分为两步:
String s = "def";
String str2 = new String(s);
第一步就是上面的第一种情况;第二步在堆内存中new出一个String对象,将str2指向该堆内存地址,新new出的String对象内容,是在字符串常量池中找到的或创建出“def”对象,相当于此时存在两份“def”对象拷贝,一份存在字符串常量池中,一份被堆内存的String对象私有化管理着。所以使用String str2 = new String("def");这种方式创建对象,实际上创建了两个对象。
2.2.2 StringBuffer(JDK 1.0) 和StringBuilder(JDK1.5)
StringBuffer和StringBuilder在功能上基本完全相同,它们都继承自AbstractStringBuilder,使用方法也都一样;可以对StringBuffer和StringBuilder对象进行改变,每次改变还是再原来的对象上发生的,不会重新new出新的StringBuffer或StringBuilder对象来。所以,当我们需要频繁修改字符串内容的时候,使用StringBuffer和StringBuilder是很好地选择。
StringBuffer和StringBuilder的最主要区别就是线程安全方面,由于在StringBuffer内大部分方法都添加了synchronized同步,所以StringBuffer是线程安全的,而StringBuilder不是线程安全的。因此,当我们处于多线程的环境下时,我们需要使用StringBuffer,如果我们的程序是线程安全的使用StringBuilder在性能上就会更优一点。
历年面试题:
String与StringBuffer的区别:
2.3 关键字
2.3.1 switch
1、switch中的参数类型
在jdk1.7 之前switch 只能支持 byte、short、char、int或者其对应的封装类以及 Enum 类型。
在jdk1.7 及1.7以后,switch也支持了String类型,如下:
String str = "abc";
switch (str) {
case "abc":
System.out.println("-----abc-----");
break;
case "aaa":
System.out.println("-----aaa-----");
break;
}
枚举类型
enum ColorEnum {
RED,
GREEN,
BLUE
}
public static void main(String[] args) {
ColorEnum color = ColorEnum.BLUE;
switch (color) {
case RED:
System.out.println("红色");
break;
case GREEN:
System.out.println("绿色");
break;
case BLUE:
System.out.println("蓝色");
break;
}
}
历年试题:
swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
2.3.2 break,continue,goto
break的作用是跳出当前循环块(for、while、do while)或程序块(switch)。在循环块中的作用是跳出当前正在循环的循环体。在程序块中的作用是中断和下一个case条件的比较。
continue用于结束循环体中其后语句的执行,并跳回循环程序块的开头执行下一次循环,而不是离开循环体。
goto:goto是java中的保留字,现在没有在java中使用。
break,continue与标签
“标签”是后面跟一个冒号的标识符,就象下面这样:label1:
对 Java 来说,唯一用到标签的地方是在循环语句之前。进一步说,它实际需要紧靠在循环语句的前方——在
标签和循环之间置入任何语句都是不明智的。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另
一个循环或者一个开关。这是由于 break 和 continue 关键字通常只中断当前循环,但若随同标签使用,它们
就会中断到存在标签的地方。如下所示:
label1:
外部循环{
内部循环 {
//...
break; //1
//...
continue; //2
//...
continue label1; //3
//...
break label1; //4
}
}
在条件 1 中,break 中断内部循环,并在外部循环结束。
在条件 2 中,continue 移回内部循环的起始处。
在条件 3 中,continue label1 却同时中断内部循环以及外部循环,并移至 label1 处。随后,它实际是继续
循环,但却从外部循环开始。
在条件 4 中,break label1 也会中断所有循环,并回到 label1 处,但并不重
新进入循环。也就是说,它实际是完全中止了两个循环。
示例:
public static void main(String[] args) {
outerCycle:
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
if(j == 5){
continue outerCycle;
}
System.out.print("("+i+","+j+") ");
}
System.out.println();
}
}
给外层循起始处加了标签(也就是说给外层循环起了个名字)“outerCycle”,在内层循环使用“continue outerCycle”时,就相当于在outerCycle这个循环中直接使用continue语句。
(0,0) (0,1) (0,2) (0,3) (0,4) (1,0) (1,1) (1,2) (1,3) (1,4) (2,0) (2,1) (2,2) (2,3) (2,4) (3,0) (3,1) (3,2) (3,3) (3,4) (4,0) (4,1) (4,2) (4,3) (4,4) (5,0) (5,1) (5,2) (5,3) (5,4) (6,0) (6,1) (6,2) (6,3) (6,4) (7,0) (7,1) (7,2) (7,3) (7,4) (8,0) (8,1) (8,2) (8,3) (8,4) (9,0) (9,1) (9,2) (9,3) (9,4)
public static void main(String[] args) {
outerCycle:
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
if(j == 5){
break outerCycle;
}
System.out.print("("+i+","+j+") ");
}
System.out.println();
}
}
运行结果
(0,0) (0,1) (0,2) (0,3) (0,4)
历年试题:
请写出下面程序的运行结果 :
public static void main(String[] args) {
int i = 0;
outer:
// 第一个标签
for (; true; ) {
inner:
//第二个标签
for (; i < 10; i++) {
prt("i = " + i);
if (i == 2) {
prt("continue");
continue;
}
if (i == 3) {
prt("break");
i++; // 注意
break;
}
if (i == 7) {
prt("continue outer");
i++; //注意
continue outer;
}
if (i == 8) {
prt("break outer");
break outer;
}
for (int k = 0; k < 5; k++) {
if (k == 3) {
prt("continue inner");
continue inner;
}
}
}
}
}
static void prt(String s) {
System.out.println(s);
}
下面是输出结果:
i = 0
continue inner
i = 1
continue inner
i = 2
continue
i = 3
break
i = 4
continue inner
i = 5
continue inner
i = 6
continue inner
i = 7
continue outer
i = 8
break outer
需要匹配后通过break关键字跳出程序块,不然继续向下执行
下面的方法,当输入为2的时候返回值是多少?()
public static int getValue(int i) {
int result = 0;
switch (i) {
case 1:
result = result + i;
case 2:
result = result + i * 2;
case 3:
result = result + i * 3;
}
return result;
}
A0 B2 C4 D10
break语句的描述中,正确的是( )
A、只中断最内层的循环
B、只中断最外层的循环
C、借助于标号,可以实现任何外层循环中断
D、只中断某一层的循环
2.4 值传递和引用传递
首先要说明的是java中是没有指针的,java中只存在值传递,只存在值传递!!! 然而我们经常看到对于对象(数组,类,接口)的传递似乎有点像引用传递,可以改变对象中某个属性的值。但是不要被这个假象所蒙蔽,实际上这个传入函数的值是对象引用的拷贝,即传递的是引用的地址值,所以还是按值传递。
需要注意的是当传递的是数组名或对象实例的话,其实传递的都是地址拷贝
public class Test3 {
public static void change(int a){
a=50;
}
public static void main(String[] args) {
int a=10;
System.out.println(a);
change(a);
System.out.println(a);
}
}
public class Test3 {
public static void change(int []a){
a[0]=50;
}
public static void main(String[] args) {
int []a={10,20};
System.out.println(a[0]);
change(a);
System.out.println(a[0]);
}
}
class Emp {
public int age;
}
public class Test {
public static void change(Emp emp)
{
emp.age = 50;
emp = new Emp();//再创建一个对象
emp.age=1000;
}
public static void main(String[] args) {
Emp emp = new Emp();
emp.age = 100;
System.out.println(emp.age);
change(emp);
System.out.println(emp.age);
System.out.println(emp.age);
}
}
历史考题
指出下列程序运行的结果 ()
public class Example {
String str = new String("good");
char[] ch = { 'a', 'b', 'c' };
public static void main(String args[]) {
Example ex = new Example();
ex.change(ex.str, ex.ch);
System.out.print(ex.str + " and ");
System.out.print(ex.ch);
}
public void change(String str, char ch[]) {
str = "test ok";
ch[0] = 'g';
}
}
A、 good and abc
B、 good and gbc
C、 test ok and abc
D、 test ok and gbc
2.5 数组
声明数组的两种方式:
int a[];
int []a;
通过上边的定义,我们只是得到了一个数组的引用。这时已经为引用分配了存储空间,但是还没有给数组对象本身分配任何空间。想要给数组对象分配存储空间,必须使用初始化表达式。
初始化数组的方式:
int a[] = new int[8];
int a[] = {0,1,2,3};
int a[] = new int[]{0,1,2,3};
默认初始化
如果我们利用int a[] = new int[6],为数组元素分配了空间,但没有初始化,Java会为他们分配默认值。如下表所示:
基本类型 默认值
boolean false
char '/u0000'(null)
byte (byte)0
short (short)0
int 0
long 0L
float 0.0f
double 0.0d
7.下面哪些语句能够正确地生成5个空字符串?
A.String a[]=new String[5];for(int i=0;i<5;a[i++]="");
B.String a[]={"","","","",""};
C.String a[5];
D.String[5] a;
E.String []a=new String[5];for(int i=0;i<5;a[i++]=null);
**5.下面哪个语句正确地声明一个整型的二维数组? **
A. int a[][] = new int[][];
B. int a[10][10] = new int[][];
C. int a[][] = new int[10][10];
D. int [][]a = new int[10][10];
E. int []a[] = new int[10][10];
**27.哪个语句创建了一个数组实例? **
A. int[] ia = new int [15];
B. float fa = new float [20];
C. char[] ca = "Some String";
D. int ia [][] = {4, 5, 6} {1, 2, 3};
数组有没有length()这个方法? String有没有length()这个方法?
请问下面程序在初始化后,a[0]和b[0]的值是多少?
String []a = new String[10];
int []b = new int[10];
下面程序的运行结果是:
int index=1;
int foo[]=new int[3];
int bar=foo[index];
int baz=bar+index;
A. baz has a value of 0
B. baz has value of 1
C. baz has value of 2
D. an exception is thrown
E. the code will not compile
下面代码的运行结果为:()
import java.io.*;
import java.util.*;
public class foo{
public static void main (String[] args){
String s;
System.out.println("s=" + s);
}
}
A 代码得到编译,并输出“s=”
B 代码得到编译,并输出“s=null”
C 由于String s没有初始化,代码不能编译通过
D 代码得到编译,但捕获到 NullPointException异常
2.6 构造函数相关
1、如果一个类中没有写任何的构造方法,JVM会生成一个默认的无参构造方法。
2、如果一个基类中写了有参构造函数,没有定义无参构造函数,基类是不会默认生成无参构造函数的。而且子类的构造函数中,如果没有显示通过super.调用基类构造函数,那么默认是调用父类的无参构造方法(即默认为super(),一般这句话省略了)。
下面哪三个描述是正确的?
A. 默认构造器初始化方法变量
B. 默认构造器有和它所在类相同的访问修饰词.
C. 默认构造器调用其父类的无参构造器.
D. 如果一个类没有无参构造器,编译器会它创建一个默认构造器.
E. 只有当一个类没有任何构造器时,编译器会为它创建一个默认构造器
以下子类B的情形哪一个是可以通过编译的:
public class A {
public A(String s){ }
}
public class B extends A {
String name = "llyB";
}
public class B extends A {
String name = "llyB";
public B(String s){}
}
public class B extends A {
String name = "llyB";
public B(String s){
super(s);
}
}
所以,只要记住,在子类的构造方法中,只要里面没有显示的通过super去调用父类相应的构造方法,默认都是调用super(),即无参构造方法,因此要确保父类有相应的构造方法。
3、Java创建对象的几种方式:
(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。
历年考题:不通过构造函数也能创建对象吗()
A 是 B 否
下列说法正确的有()
A. class中的constructor不可省略
B. constructor必须与class同名,但方法不能与class同名
C. constructor在一个对象被new时执行
D.一个class只能定义一个constructor
4、构造函数调用顺序
在Java中,子类的构造过程中必须调用其父类的构造函数,是因为有继承关系存在时,子类要把父类的内容继承下来。但如果父类有多个构造函数时,该如何选择调用呢?
第一个规则:子类的构造过程中,必须调用其父类的构造方法。一个类,如果我们不写构造方法,那么编译器会帮我们加上一个默认的构造方法(就是没有参数的构造方法),但是如果你自己写了构造方法,那么编译器就不会给你添加了,所以有时候当你new一个子类对象的时候,肯定调用了子类的构造方法,但是如果在子类构造方法中我们并没有显示的调用基类的构造方法,如:super(); 这样就会调用父类没有参数的构造方法。
第二个规则:如果子类的构造方法中既没有显示的调用基类构造方法,而基类中又没有无参的构造方法,则编译出错,所以,通常我们需要显示的:super(参数列表),来调用父类有参数的构造函数,此时无参的构造函数就不会被调用。
总之,一句话:子类没有显示调用父类构造函数,不管子类构造函数是否带参数都默认调用父类无参的构造函数,若父类没有则编译出错。
历年考题:下面是People和Child类的定义和构造方法,每个构造方法都输出编号。在执行new Child("mike")的时候都有哪些构造方法被顺序调用?请选择输出结果 ( )
class People {
String name;
public People() {
System.out.print(1);
}
public People(String name) {
System.out.print(2);
this.name = name;
}
}
class Child extends People {
People father;
public Child(String name) {
System.out.print(3);
this.name = name;
father = new People(name + ":F");
}
public Child() {
System.out.print(4);
}
}
A312 B 32 C 432 D 132
5、override与Overloading
Override(重写):
在子类中定义与父类具有完全相同的名称和参数的方法,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,是子类与父类之间多态性的一种体现。特点如下:
(1)子类方法的访问权限只能比父类的更大,不能更小(可以相同);
(2)如果父类的方法是private类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法;
Overload(重载):
同一个类中可以有多个名称相同的方法,但方法的参数个数和参数类型或者参数顺序不同;
关于重载函数返回类型能否不一样,需分情况:
(1)如果几个Overloaded的方法的参数列表不一样(个数或类型),它们的返回者类型当然也可以不一样;
(2)两个方法的参数列表完全一样,则不能通过让其返回类型的不同来实现重载。
(3)不同的参数顺序也是可以实现重载的;
(4)构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载。
2.7 静态代码块执行顺序
执行顺序:1.静态代码块 --> 2.普通代码块 --> 3.构造方法
需要明白的是,1是类级别的,2和3是实例级别的,所以在父子类关系中,上述的执行顺序为:
父类静态代码块-->子类静态代码块-->父类普通代码块-->父类构造方法-->子类代码块-->子类构造方法;
也就是上到下(父类到子类)先走完 类级别的(静态的)--> 再依次走完父类的所有实例级别代码 --> 再走子类所有实例级别代码
历史题目:
如下代码的输出结果:
public class HelloB extends HelloA {
public HelloB() {
System.out.println("-----------HelloB 构造方法------------");
}
{
System.out.println("I’m B class");
}
static{
System.out.println("static B");
}
public static void main(String[] args){
new HelloB();
}
}
class HelloA{
public HelloA(){
System.out.println("-----------HelloA 构造方法------------");
}
{
System.out.println("I’m A class");
}
static{
System.out.println("static A");
}
}
输出结果:
static A
static B
I’m A class
-----------HelloA 构造方法------------
I’m B class
-----------HelloB 构造方法------------
下面程序的运行结果是什么()
class HelloA {
public HelloA() {
System.out.println("HelloA");
}
{ System.out.println("I'm A class"); }
static { System.out.println("static A"); }
}
public class HelloB extends HelloA {
public HelloB() {
System.out.println("HelloB");
}
{ System.out.println("I'm B class"); }
static { System.out.println("static B"); }
public static void main(String[] args) {
new HelloB();
}
}
答案:
static A
static B
I'm A class
HelloA
I'm B class
HelloB
2.8 面向对象
1、Java面向对象的基本思想之一是封装细节并且公开接口。Java语言采用访问控制修饰符来控制类及类的方法和变量的访问权限,从而向使用者暴露接口,但隐藏实现细节。访问控制分为四种级别:
(1)public: 用public修饰的类、类属变量及方法,包内及包外的任何类(包括子类和普通类)均可以访问;
(2)protected: 用protected修饰的类、类属变量及方法,包内的任何类及包外那些继承了该类的子类才能访问(此处稍后解释),protected重点突出继承;
(3)default: 如果一个类、类属变量及方法没有用任何修饰符(即没有用public、protected及private中任何一种修饰),则其访问权限为default(默认访问权限)。默认访问权限的类、类属变量及方法,包内的任何类(包括继承了此类的子类)都可以访问它,而对于包外的任何类都不能访问它(包括包外继承了此类的子类)。default重点突出包;
(4)private: 用private修饰的类、类属变量及方法,只有本类可以访问,而包内包外的任何类均不能访问它。
修饰符 | 当前类 | 同 包 | 子 类 | 其他包 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
2、final修饰的类不能被继承,没有子类。
3、abstract修饰的类不能被实例化,必须被子类继承。类只要有一个抽象方法就必定是抽象类,但抽象类不一定要有抽象方法。声明方式必须是:abstract void C();
不能带我实现体大括号。
历史题目:
1、如下代码:
class A {
A() { }
}
class B extends A {
}
哪两个说明是正确的?
A. B类的构造器应该是 public.
B. B类的构造器应该是没有参数
C. B类的构造器应该调用this().
D. B类的构造器应该调用super().
是否可以继承String类?
String类是final类故不可以继承。
**以public修饰的类如:public class Car{…} 则Car( ) **
A、可被其它程序包中的类使用 B、仅能被本程序包中的类使用
C、不能被任意其它类使用 D、不能被其它类继承
2.9 equals与==的区别
(1)==是一个运算符,它比较的是值
对于基本数据类型,直接比较其数据值是否相等。如果是不同的基本数据类型之间进行比较,则遵循基本数据类型间运算的转换原则。如下:
if(12 == 12.0){
System.out.println("-----12 == 12.0-------");
}
此时打印了-----12 == 12.0-------,因为低一级的int类型的12自动转换为高一级的float类型
对于引用类型,==比较的还是值,只不过此时比较的是两个对象变量的内存地址。所以,用==来比较对象,实际上是判断这两个对象是否是同一个new出来的对象,或者是否是一个对象赋值给另一个对象的情况。如:
String s1 = new String("abc");
String s2 = s1;//将s1对的内存地址赋给了s2,此时s1==s2返回true;
(2)equals
equals方法是属于Object类的一个方法,其实现源码如下:
public boolean equals(Object obj) {
return (this == obj);
}
可以看到,其实equals方法里面用的还是==运算符,所以对于那些没有重写过Object类的equals方法来说,==和equals方法是等价的!
然而,很多类都自己去重写了equals方法,比如String类、所有基本数据类型的包装类等
String类的equals源码如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
首先判断是否是同一个new出来的对象,即判断内存地址是否相同;如果不同则判断对象中的内容是否相同。
Integer类的equals方法如下:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
直接转成判断值是否相等了。
因此,对于String类和所有基本数据类型的包装类来说,equals方法就是判断其内容是否相等。对于其他类来说,要具体看其是否重写了equals方法及具体业务实现。
另:对于基本数据类型来说,使用equals方法,需要用该基本类型对应的包装类,因为equals是针对对象来使用的!
下面程序的运行结果是()
String str1 = "hello";
String str2 = "he" + new String("llo");
System.err.println(str1 == str2);
其它基础
&和&&的区别
&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。
**下面的语句会产生什么样的输出? **
System.out.println(4&7);
A.4
B.5
C.6
D.7
E.0
5、try、catch、finally执行顺序问题
14. 如下代码:
public class Foo {
public static void main(String[] args) {
try {
return;
} finally {
System.out.println( "Finally" );
}
}
}
输出结果是什么?
A. Finally
B.编译失败
C. 代码正常运行但没有任何输出.
D. 运行时抛出异常
下面函数将返回?
publicstaticintfunc (){
try{
return 1;
}catch(Exception e){
return 2;
}finally{
return 3;
}
}
A、1 B、2 C、3 D、编译错误