1.Java中的基本数据类型有哪些?
byte short int long float double boolean char
2.面向对象的特征有哪些?
抽象、继承、封装、多态。
抽象是将一类对象的共同特征总结出来的过程。包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类;得到继承信息的类被称为子类。
封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。将具体的实现细节对调用者隐藏掉。
多态是指允许不同的子类型的对象对同一消息做出不同的响应。工厂方法模式中就是充分利用了多态的特性,结合一些具体的实现细节,比如继承、方法重载等,根据里式替换原则,在调用父类的地方使用子类对象,可以实现更多样的行为。
3.访问修饰符有哪些?区别是什么?
4.String是基本数据类型吗?对String类型的理解。
String不是基本类型,是引用类型,基本类型只有八个。Java中类型包括基本类型、引用类型 和 枚举类型。
String类是java.lang包下的重要组成。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
java程序中的所有字符串字面量(如“abc”)都作为此类的实例。
字符串是常亮:意味着它们的值在创建之后不能更改。字符串缓冲区StringBuffer支持可变的字符串。因为String对象是不可变的,所以可以共享。
由于String内部实际上是一个char数组,因此:
String str = "abc"; 等效于: char data[] = {'a', 'b', 'c'}; String str = new String(data);
String的equals方法
public boolean equals(Object anObject)
参数是String类型且与此字符串表示相同字符序列,结果为true。即比较的是内容,而不是内存地址。
下面这句代码在内存中创建了几个对象?
String s1 = new String("abc");//创建了两个对象,分别保存在常量池和堆内存中new进堆内存,常量池一个对象“abc”,堆内存一个对象“abc”的一个副本。这样是创建了 两个对象。
内存中有一个常量池,当我们创建常量时,系统先看常量池中有没有这个常量,如果有,则不创建对象,直接引用这个常量。
另外,java语言中的“+”字符串拼接符号,是通过StringBuilder和append来实现的,而且是每一个“+”都会创建一个StringBuilder对象,因此效率非常低。但是这里注意,通过+拼接虽然是通过在创建StringBuilder来实现,但是最终生成的字符串并不是存储在堆内存中,而是仍然保存在常量池中,测试代码如下:
String s = "abc" + "d"; String s1 = "abcd"; System.out.println(s == s1); // true
5.float f = 3.4;是否正确?
答:不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于向下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f = (float)3.4;或者写成float f = 3.4f; 。
6.int和Integer有什么区别?
答:Java语言虽然是面向对象的编程语言,但是为了操作方便,依然引入了int等并不是表示对象的八种基本数据类型。让int等基本数据类型可以像其他对象那样完成某些动作,Java将八大基本数据类型都配备了封装类,Integer就是int的封装类。并且添加了自动拆装箱特性,开发者可以轻松的实现int与Integer之间的转换。
下面一个面试题:
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150; System.out.println(f1 == f2);// true System.out.println(f3 == f4);// false
解析:
当一个int类型赋值给Integer对象的时候会隐式地调用valueOf方法,而valueOf方法内部又使用了一个叫IntegerCache 的静态内部类。这个类完成了一系列静态功能,使得:如果整型字面量的值在 -128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象。
7. &和&& 的区别?
答:&&是“短路与”逻辑运算符,左面的表达式如果是false那么程序不会继续判断右面的表达式的值,而&不管左面的值是否为false都会完成两遍的逻辑计算。在大多数场合下我们需要的是&&而不是&。
8.Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
答:Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后进行下取整。
9.switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?
答:在Java 5以前,switch(expr)中,expr只能是byte、short、char、int。从Java 5开始,Java中引入了枚举类型,expr也可以是enum类型,从Java 7开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。
10.用最有效率的方法计算2乘以8?
答: 2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。
11.数组有没有length()方法?String有没有length()方法?
答:数组没有length()方法,有length 的属性。String 有length()方法。JavaScript中,获得字符串的长度是通过length属性得到的。
12.构造器(constructor)是否可被重写(override)?
答:构造器不能被继承,因此不能被重写,但可以被重载。
13.请说明一下equals()方法和hash code的关系,实现equals()方法的重写。
答:如果两个对象x和y满足x.equals(y),那么他们的哈希码应当相同。
Java对于 equals方法和hashCode方法是这样规定的:
(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同; (2)如果两个对象的hashCode相同,它们并不一定相同。
equals()方法的特性:
自反性(x.equals(x)必须返回true); 对称性(x.equals(y)返回true时,y.equals(x)也必须返回true); 传递性(x.equals(y)和y.equals(z)都返回true时,x.equals(z)也必须返回true); 一致性(当x和y引用的对象信息没有被修改时,多次调用x.equals(y)应该得到同样的返回值); 对于任何非null值的引用x,x.equals(null)必须返回false。
equals()方法和hashCode()方法重写:
//经典方式(17和31散列码思想) public class User { private String name; private int age; private String passport; //getters and setters, constructor @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof User)) { return false; } User user = (User) o; return user.name.equals(name) && user.age == age && user.passport.equals(passport); } //Idea from effective Java : Item 9 @Override public int hashCode() { int result = 17; result = 31 * result + name.hashCode(); result = 31 * result + age; result = 31 * result + passport.hashCode(); return result; } }
//JDK7+ import java.util.Objects; public class User { private String name; private int age; private String passport; //getters and setters, constructor @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof User)) { return false; } User user = (User) o; return age == user.age && Objects.equals(name, user.name) && Objects.equals(passport, user.passport); } @Override public int hashCode() { return Objects.hash(name, age, passport); } }14.是否可以继承String类?
答:String 类是final类,不可以被继承。继承String本身就是一个错误的行为,对String类型最好的重用方式是关联关系(Has-A)和依赖关系(Use-A)而不是继承关系(Is-A)。
15.当一个对象被当做参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
答:是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值实际上是对象的额内存地址。对象中的属性可以在被调用过程中被改变。但是如果是将String或int等变量直接作为参数传入方法,修改其值时无法对调用方起到影响的。正是如此,在Java编写的代码中才会出现大量的Wrapper类(将需要通过方法调用修改的变量置于一个Wrapper类中,再将Wrapper对象传入方法)。
public class Demo { public static void main(String[] args) { int i = 0; change(i);// 将变量直接传入 System.out.println(i);// 0 调用方 } public static void change(int i){ i = 10; } }
public class Demo { public static void main(String[] args) { A a = new A(); System.out.println(a.age);// 0 change(a); System.out.println(a.age);// 10 Wrapper类A将age进行封装 } public static void change(A a){ a.age = 10; } } class A { public int age; }按值传递指的是,在方法调用时,传递的参数是按值的拷贝传递。但是Wrapper类则是将引用的对象地址值传递给参数的。注意这点区别。
16.抽象类与接口异同?
同: 1.抽象类和接口可以定义引用,但是不能直接实例化。 2.一个类继承了抽象类或接口,除非是其本身也是抽象类,否则,必须实现全部抽象方法。 异: 1.抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器,方法也必须全是抽象方法。 2.抽象类的成员可以由四种访问权限修饰,但是接口中的成员全是public 3.抽象类中可以定义成员变量,接口中定义的成员变量实际上都是常量。 4.有抽象方法,一定是抽象类,但反过来抽象类,不一定有抽象方法。 5.继承关系:接口可以继承接口,抽象类可以实现接口,接口不能继承抽象类
17.静态嵌套类(Static Nested Class)与内部类(Inner Class)的区别?
18.抽象方法能否被static修饰?能否被Native修饰?能否被synchronized修饰?
答:都不能。抽象方法需要子类重写,static修饰的类静态类无法被重写。Native是用来修饰本地方法的修饰符,不属于Java代码。synchronized和方法的实现细节有关,抽象方法没有方法体,即没有实现细节,因此无法被synchronized修饰。
19.静态方法能否调用非静态方法?
答:不可以,静态方法只能访问静态成员,因为非静态方法的调用首先要创建对象,在调用静态方法时,可能对象并没有被正确的初始化。
20.