javaSE 基础

199 阅读9分钟

java语法有没有goto语句?

goto是java中的保留字,但目前版本的java没有使用。

&和&&的区别

&运算符有两种用法:1,按位与。2,逻辑与。

&&之所以称为短路运算是因为,如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。,例如在验证用户登录时判定用户名不是 null 而且不是空字符串,应 当写为username!=null&&!username.equals(""),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的 equals 比较,否则会产生NullPointerException 异常。

注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。

java中如何跳出当前多重嵌套循环?

在最外层循环前加一个标记如a,然后用break a;可以跳出多重循环。(java中支持带标签的break和continue语句,但是一般避免使用的带标签的break和continue,因为他不会是你的程序变得优雅,很多时候会起反作用)

两个对象值相同(x.equals(y)),但却可以有不同的hashCode,这句话对不对?

不对,如果两个对象x和y满足x.equals(y) == true,那么他们的哈希码(hashCode)应当相同。

java对equals方法和hashCode方法是这样规定的:1,如果两个对象相同(equals方法返回true),那么他们的hashCode值一定要相同;2,如果两个对象的hashCode相同,他们并不一定相同。当然,你未必要按照要求去做,但是你如果违背了上述原则就会发现在使用容器时,相同的对象可以出现在set集合中,同事增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突会造成存取性能急剧下降。)

首先equals方法必须满足自反性(x.equals(x)必须返回true),对称性,传递性,一致性,而且对于任何非null值的引用x,x.equals(null)必须返回false。

是否可以继承String?

String是final类,不可以被继承。

继承String本身就是一个错误行为,对String类型最好的重用方式是关联关系和依赖关系,而不是继承关系。

当一个对象被当作参数传递到一个方法后,此方法可以改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

是值传递,java语言的方法调用只支持参数的值传递,当一个对象实例被作为参数传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用的过程中改变,但对对象引用的改变是不会影响到调用者的。c++和c#中可以通过传递引用或输出参数来改变传入的参数的值。说明:java中没有传引用实在是非常的不方便,这一点在java8中仍然没有得到改进,正式如此在java编写的代码中才会出现大量的Wrapper类(将需要通过方法调用修改的引用置于一个Wrapper类中,再将Wrapper对象传入方法),这样的做饭只会让代码变得臃肿,尤其是让从c和c++转型为java程序员的开发者无法容忍的。

重载和重写的区别?重载的方法能否根据返回类型进行区分?

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同,参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类重写的方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。

方法重载的规则:

1. 方法名一致,参数列表中的参数的顺序,类型,个数不同。

2. 重载与方法的返回值无关,存在于父类和子类,同类中。

3. 可以抛出不同的异常,可以有不同的修饰符。

方法重写的规则:

1. 参数列表必须与被重写的方法一致,返回类型必须完全与被重写方法的返回类型一致。

2. 构造方法不能被重写,声明为final的方法不能被重写,声明为static的方法不能被重写,但是能够被再次声明。

3. 访问权限不能比父类中被重写的方法的访问权限更低。

4. 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常,但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之,则可以。

为什么函数不能根据返回类型来区分重载?

调用方法时无法指定该方法的返回值类型,编译器不知道你要调用哪个函数。

例如:

float max(int a, int b); 
int max(int a, int b); 

当调用max(1,2);时无法确定调用的是哪一个,单从这一点来说,仅返回值类型不同的重载是不应该被允许的。

在比如下面这两个方法来说,虽然他们有相同的名字和自变量,但其实是很容易区分的:

void f() {} 
int f() {} 

若编译器可以根据上下文(语境)明确判断出含义,比如在int x = f();中,那么这样做是完全没有问题的,然而,我们也可能调用一个方法,同时忽略返回值,我们通常吧这称为“为他的副作用调用一个方法”,因为我们关心的不是返回值,而是方法调用的其他效果。所以加入我们像下面这样调用方法:f();java怎样判断f()具体调用的方法呢?而且别人该如何识别并理解代码呢?由于存在这一类问题,所以不能将函数的返回值作为区分重载的条件。函数的返回值只是作为函数运行之后的一个状态,他是保持方法的调用者与被调用者进行通信的关键,并不能作为某个方法的标识。

抽象类(abstract class)和接口(interface)有什么异同?

不同:

抽象类
1,抽象类中可以定义构造器
2,可以有抽象方法和具体方法
3,接口中的成员全都是public的
4,抽象类中可以定义成员变量
5,有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。
6,抽象类中可以包含静态方法。
7,一个类只能继承一个抽象类
接口:
1:接口中不能定义构造器
2:方法中全部都是抽象方法
3:接口中定义的成员变量实际上都是常量
4:接口中不能有静态方法
5:一个类可以实现多个接口

相同:

1:不能够实例化
2:可以将抽象类和接口作为引用类型
3:一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类

阐述静态变量和实例变量的区别?

静态变量:是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建了多少个对象,静态变量在内存中有且仅有一个拷贝;

实例变量:必须依存于某一实例,首先要创建对象然后通过对象才能访问到他,静态变量可以实现让对个对象共享内存

String s = "Hello"; s = s + "world!";这两行代码执行后,原始的String对象中的内容到底改变了没有?

没有,因为String被设计成不可改变的类,所以他的所有对象都是不可改变的。如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销,因为String对象建立之后不能改变,所以对于每一个不同的字符串,搜需要一个String对象来表示,这是,应该考虑使用StringBuffer类,他允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种对象转换十分容易。

java中实现多态的机制是什么?

靠的是父类或者接口定义的引用变量可以指向子类或者具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

调用下面的方法得到的返回值是什么?

public int getNum(){
   try { 
    int a = 1/0; 
    return 1; 
   } catch (Exception e) { 
    return 2; 
   }finally{ 
    return 3; 
   }
}

代码在走到第3行的时候遇到了一个MathException,这时第四行的代码就不会执行了,代码直接跳转到catch语句中,走到第6行的时候,异常机制有这么一个原则如果在catch中遇到了return或者异常等能使该函数终止的话那么有 finally 就必须先执行完 finally 代码块里面的代码然后再返回值。因此代码又跳到第 8 行,可惜第 8 行是一个return语句,那么这个时候方法就结束了,因此第6行的返回结果就无法被真正返回。如果finally仅仅是处理了一个释放资源的操作,那么该道题最终返回的结果就是2。因此上面返回值是3。