java基础
1. java 有没有goto语句?
没有goto语句,称为保留关键字 因为在C语言使用的时候 发现会吧逻辑顺序搞的很混乱 代码的可读性会变的很差,所以java当中就没有去使用
2. &和&&的区别
最终的运行结果都差不多,只不过一个速度会快一点一个慢一点
&& 左边为false 就不运行 而&左边为false照样会判断右边 这样效率就差很多 一般都推荐用效率高一点的&&
3. 在java中,如何跳出当前的多重嵌套循环
标号去跳出当前循环 跳到最外层
ok:
for ( int i= 0 ; i< 100 ; i++ ) {
if ( i== 6 ) break ok;
}
break跳出当前循环 排除异常也可以跳出循环
for ( int i = 0 ; i< 100 ; i++ ) {
throw new Exception ( ) ;
}
4. 两个对象值相同(x.equals(y)==true),但却可有不同的HashCode ,这句话对吗
两个对象的值相同的时候 hashcode一定相同
两个对象的hashcode相同的时候 值不一定相同
例子:hashcode是一个容器 可以装很多的对象的值 他会分配空间出来给装值 当a1的值和a2的值同时装进hashcode里面的一个地方时候 就会开始用equals对比是否相同
5. 是否可以继承String
是不能被继承的,因为String里面有final修饰符 而final修饰的类是不能被继承的,实现细节不允许被改变
6. 当一个对象被当做参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
public class test1 {
public static void change ( int i, int j) {
int temp = i;
i = j;
j = temp;
}
public static void main ( String [ ] args) {
int a = 1 ;
int b = 2 ;
change ( a, b) ;
System . out. println ( a) ;
System . out. println ( b) ;
}
}
public class test1 {
public static void change ( int [ ] counts) {
counts[ 0 ] = 6 ;
System . out. println ( counts[ 0 ] ) ;
}
public static void main ( String [ ] args) {
int [ ] count = { 1 , 2 , 3 , 4 , 5 } ;
change ( count) ;
for ( int i= 0 ; i< count. length; i++ ) {
System . out. println ( count[ i] ) ;
}
}
}
public class test1 {
public static void add ( A a) {
a = new A ( ) ;
a. i++ ;
}
public static void main ( String [ ] args) {
A a = new A ( ) ;
add ( a) ;
System . out. println ( a. i) ;
}
}
class A {
int i = 0 ;
}
public class test1 {
String str = new String ( "good" ) ;
char [ ] ch = { 'a' , 'b' , 'c' } ;
public void change ( String str, char ch[ ] ) {
str = "test ok" ;
ch[ 0 ] = 'g' ;
}
public static void main ( String [ ] args) {
test1 t1 = new test1 ( ) ;
t1. change ( t1. str, t1. ch) ;
System . out. print ( t1. str+ " and " ) ;
System . out. println ( t1. ch) ;
}
}
class A {
int i = 0 ;
}
总结:传入的是基本类型 那么就是值传递 只改变副本不改变原始的值,如果传入的是引用类型 那么就相当于引用传递 会改变原始的值 当然string类型除外
a.传递值的数据类型:八种基本数据类型和String(这样理解可以,但是事实上String也是传递的地址,只是string对象和其他对象是不同的,
string对象是不能被改变的,内容改变就会产生新对象。那么StringBuffer就可以了,但只是改变其内容。不能改变外部变量所指向的内存地址)。
b.传递地址值的数据类型:除String以外的所有复合数据类型,包括数组、类和接口
public class test1 {
public static void main ( String [ ] args) {
int val;
StringBuffer sb1, sb2;
val = 10 ;
sb1 = new StringBuffer ( "apples" ) ;
sb2 = new StringBuffer ( "pears" ) ;
System . out. println ( "val is" + val) ;
System . out. println ( "sb1 is" + sb1) ;
System . out. println ( "sb2 is" + sb2) ;
System . out. println ( "" ) ;
modify ( val, sb1, sb2) ;
System . out. println ( "..." ) ;
System . out. println ( "" ) ;
System . out. println ( "val is " + val) ;
System . out. println ( "sb1 is " + sb1) ;
System . out. println ( "sb2 is " + sb2) ;
}
public static void modify ( int a, StringBuffer r1, StringBuffer r2) {
System . out. println ( "..." ) ;
a= 0 ;
r1 = null ;
r2. append ( "taste good" ) ;
System . out. println ( "a is" + a) ;
System . out. println ( "r1 is" + r1) ;
System . out. println ( "r2 is" + r2) ;
}
}
* * 因此,对复制的引用所调用的方法更改的是同一个对象。* * 复制完之后进行更改的就是改原始值了
class Book {
String name;
private float price;
Book ( String n, float p ) {
name = n;
price = p;
}
static void change ( Book a_book, String n, float p ) {
a_book. name = n;
a_book. price = p;
}
public void output ( ) {
System. out. println ( "name:" + name + "/t" + "price: " + price) ;
}
}
public class PassAddr {
public static void main ( String [ ] args ) {
Book b = new Book ( "java2" , 32.5 f) ;
System. out. print ( "beforecall:/t" ) ;
b. output ( ) ;
b. change ( b, "c++" , 45.5 f) ;
System. out. print ( "aftercall:/t" ) ;
b. output ( ) ;
}
}
总结::是值传递。Java编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
7.重载(overload)和重写(override)的区别?重载的方法能否根据返回类型进行区分?
重载:同名不同参,只要参数不一样写多少个都没关系,一般都用于构造方法当中,编译时的多态性,重载发生在一个类当中
重写:对父类方法进行重写,保证自己的方法跟其他的方法不一样,有自己的独特性,运行时的多态性,重写发生在子类与父类当中
区分:不能根据返回类型进行区分,函数的返回值只是作为函数运行之后的一个“状态”
他是保持方法的调用者与被调用者进行通信的关键。并不能作为某个方法的“标识” 因为调用时不能指定类型信息,
编译器不知道你要调用哪个函数。
8.为什么函数不能根据返回类型来区分重载
因为调用时不能指定类型信息,编译器不知道你要调用哪个函数。
当调用max(1 , 2 ); 时无法确定调用的是哪个,单从这一点上来说,仅返回值类型不同的重载是不应该允许的。
float max ( int a, int b) ;
int max ( int a, int b) ;
void f ( ) { }
int f ( ) { }
9.char型变量中能不能存储一个中文汉字,为什么?
char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,
所以,char型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在
unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。
补充 说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。
10.抽象类(abstract class)和接口(interface)有什么异同?
相同点:
1. 抽象类和接口都不能被实例化,但是可以定义抽象类和接口类型的引用
2. 一个类如果继承了抽象类和接口,必须要对其中的抽象方法全部实现,接口中方法默认的是public abstract修饰 否则就要声明为抽象类
不同点:
3. 抽象类可以有构造方法,抽象方法和具体方法
接口中不能有构造方法,而且其中的方法全部都是抽象方法
4. 抽象类中的成员可以是private,默认的,protected,public
接口中的成员全部都是public
5. 抽象类可以定义成员变量
接口中定义的成员变量都是常量 public static final修饰
11.抽象的方法是否可都同时是静态的?是否可同时是本地方法?
都不能,因为静态的方法是无法被重写的,因此二者是矛盾的
而本地方法是由本地代码实现的方法,而抽象方法是没有实现的,也是矛盾的
12.阐述静态变量和实例变量的区别?
语法区别:静态变量是用static修饰 ,实例变量是没有static修饰
运行区别:静态变量在类中,不属于实例对象,属于类所有,只要程序加载了字节码,不用创建实例对象静态变量就会被分配空间,已经可以使用
实例变量是某个对象的属性,只有实例化对象后,才会被分配空间,才能使用
类变量是所有对象共有的,其中一个对象将它值改变,其他对象得到的就是改变后的结果
而实例变量则属于对象私有,其一个对象将其值改变,不影响其他对象
13.==和equals的区别?
==的作用:
1. 基本类型:比较值是否相等
基本类型从小到大排列:
boolean<byte1<char2<short2<int4<float4<long8<double8
2. 引用类型:比较内存地址是否相等
equals的作用:
3. 引用类型:默认情况下,比较内存地址是否相等,可以按照需求逻辑,重写对象的equals方法
重写equals要求:
1、自反性:对于任何非空引用x,x.equals(x)应该返回true。
2、对称性:对于任何引用x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。
3、传递性:对于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。
4、一致性:如果x和y引用的对象没有发生变化,那么反复调用x.equals(y)应该返回同样的结果。
5、非空性:对于任意非空引用x,x.equals(null)应该返回false。
14.break和continue的区别?
1. break只能用于循环语句和switch语句中,而continue只能用于循环语句中
2. continue只结束本次循环,而不是终止整个循环,break语句则是结束整个循环过程,不再判断执行循环的条件是否成立
15.面向对象都有哪些特性以及你对这些特性的理解
1. 继承
就是在已有类的基础之上去进行继承这些信息的过程,提供继承信息的类称为超类,得到这些信息的类称为子类
2. 封装
就是把数据和操作数据的方法绑定起来,对数据的访问只能通过定义的接口,编写类就是为了封装这些数据和操作数据的方法,可以说封装就是隐藏一切可以隐藏的东西,只向外界提供最简单的编程接口
3. 多态性
就是用同样的对象引用调用同样的方法但是做了不同的事情,多态性分为编译时的多态性和运行时的多态性,重载编译多态性,重写就是运行时的多态性
4. 抽象
抽象是将一类对象的共同特征总结出来构造类的过程,包含数据抽象和行为抽象两方面,抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
16.String s = “Hello”;s = s+“world”!;这两行代码执行后,原始的String对象中的内容到底变了没有?
没变,因为string类是final修饰的,因此不能修改不能继承,实例的信息失在创建的时候提供,并且在整个生命周期中都不可改变,s只是不指向原来的对象,而是指向了另一个string对象,原来的那个对象还存在内存中。
17.访问权限修饰符public、private、protected、以及不写(默认时)的区别
类的成员不写修饰默认为default,默认对于同一个包中都是其他类相当于公开public,对于不是同一个包中的其他类相当于私有private,受保护protected对子类相当于公开,对不是同一包中的没有父子关系的相当于私有
作用域 当前类 同包类 子类 其他类 public √ √ √ √ protected √ √ √ × default √ √ × × private √ × × ×
18.如何理解clone对象
复制对象:首先要分配一个和源对象同样大小的控件,在这个空间中创建一个新的对象
1. 使用new操作符创建一个对象
2. 使用clone方法复制对象
new:分配内存 程序执行到new操作的时候先看new操作符后面的类型,知道类型才能知道分配多大的内存空间,分配之后调用构造函数,填充对象的各个域,这就叫初始化,构造方法返回后,一个对象创建完毕,可以把引用发布到外部,在外部就可以使用这个引用来操纵这个对象
clone:先分配内存,调用clone方法时,分配的内存和源对象就是调用clone方法的对象相同,然后再使用源对象中对应的各个域,填充新对象的域,填充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部去。
浅复制:被复制的对象所有变量都含有原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象,换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象
深复制:被复制对象的所有变量都含有与原来的对象相同的值,出去哪些引用过其他对象的变量,哪些引用其他对象的变量将指向被复制过的新对象,而不再是原来的哪些被引用的对象,换言之,深复制把要复制的对象所引用的对象都复制了一遍
Java的clone()方法
⑴clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:
①对任何的对象x,都有x.clone() !=x//克隆对象与原对象不是同一个对象
②对任何的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样
③如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。
⑵Java中对象的克隆
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。
继承自java.lang.Object类的clone()方法是浅复制, 在编写程序时要注意这个细节。
Clone()方法的使用
Clone()方法的使用比较简单,注意如下几点即可:
a. 什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别还是reference variable
b. 调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException。
复制引用:下面p和p1只是引用而已,他们都指向了一个相同的对象Person ( 23 , "zhang" ) 。 可以把这种现象叫做引用的复制。
Person p = new Person ( 23 , "zhang" ) ;
Person p1 = p;
复制对象
Person p = new Person ( 23 , "zhang" ) ;
Person p1 = ( Person ) p. clone ( ) ;
19.java中实现多态的机制是什么
java多态的实现机制是父类或接口定义的引用变量可以指向子类或实现类的实例对象,而程序调用的方法在运行期才动态绑定,
就是引用变量所指向的具体实现对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法.
多态机制包括静态多态(编译时多态)和动态多态(运行时多态),静态多态比如说重载,动态多态是在编译时不能确定调用哪个方法,
得在运行时确定。动态多态的实现方法包括子类继承父类和类实现接口。当多个子类上转型(不知道这么说对不)时,
对象调用的是相应子类的方法,这种实现是与JVM有关的。
20.逻辑运算中的“短路现象”是指什么
在使用逻辑操作符的时候,会遇到短路现象,就是一旦能够明确无误的确定整个表达式的值,就不会在计算其余的部分,所以整个逻辑表达式靠后的部分有可能不会被运算.
例如,当&&的第一个操作数的值为false时,直接返回第一个操作数的值,不会在对第二个操作数进行计算