您的位置:首页 > 编程语言 > Java开发

langsin-Java常见笔试

2013-02-18 21:38 253 查看
一、字符串
public static void main(String[] args) {
test01();
test02();
test03();
}

private static void test01() {
/* 共创建两个对象:String pool(String池中创建一个),堆内存中也创建了一个对象 */
String s = new String("abc");
/* 由于String pool已有"abc",所以不创建对象 */
String s1 = "abc";
/* 在堆内存中创建"abc"对象,只要使用new,就会创建新的对象 */
String s2 = new String("abc");
/* 和s1一样,指向string pool中的对象 */
String s3 = "abc";

System.out.println(s == s1); // false
System.out.println(s == s2); // false
System.out.println(s1 == s2); // false
System.out.println(s1 == s3); // true
}

private static void test02() {
/* 共创建两个对象:String pool(String池中创建一个),堆内存中也创建了一个对象 */
String s = new String("abc");
/* 由于String pool已有"abc",所以不创建对象 */
String s1 = "abc";
/* 在堆内存中创建"abc"对象,只要使用new,就会创建新的对象 */
String s2 = new String("abc");

/*
* 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object)
* 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用
*/
System.out.println(s == s.intern()); // false
System.out.println(s1 == s1.intern()); // true
System.out.println(s1 == s.intern()); // true
System.out.println(s1 == s2.intern()); // true
System.out.println(s.intern() == s2.intern()); // true
}

private static void test03() {
String hello = "hello";
String hel = "hel";
String lo = "lo";
System.out.println(hello == "hel" + "lo"); // true
/* 当使用变量拼接字符串时,会在堆内存中创建一个新的对象 */
System.out.println(hello == "hel" + lo); // false
}


二、Static类加载过程

public class StaticTest {

/* 第1步:调用构造方法,对于使用到的count1和count2静态变量,jvm会进行默认初始化,值为0,++操作后,两者值均为1 */
private static StaticTest st = new StaticTest();
/* 第2步:count1没有显示的被赋值,且在步骤1中已初始化,所以不进行操作 */
public static int count1;
/* 第3步:count2被显示的赋值为0,所以最后打印的值为0 */
public static int count2 = 0;

private StaticTest() {
count1++;
count2++;
}

public static StaticTest getInstance() {
return st;
}

public static void main(String[] args) {
StaticTest st = StaticTest.getInstance();
System.out.println("count1:" + st.count1); // 1
System.out.println("count2:" + st.count2); // 0
}
}


三、参数传递

public class ParamTest {

public void changeInt(int a) {
a = 3;
}

public void changePoint(Point p) {
p.x = 5;
p.y = 6;
}

public void changeString(String s) {
s = "cba";
}

public static void main(String[] args) {
/* 8个基本数据类型,传递的只是一份拷贝,所以不会改变 */
int a = 1;
ParamTest test = new ParamTest();
test.changeInt(a);

System.out.println(a); // 1
/*************************************/
/* 在堆内存中new了一个对象,p这个引用指向new的这个对象;传递的是引用的地址,changePoint中的参数p也指向new的对象 */
Point p = new Point(1, 2);
test.changePoint(p);
System.out.println("x:" + p.x + ";y:" + p.y); // 5,6
/*************************************/
/*
* (1)s指向string pool中"abc"对象;
* (2)调用changeString方法,方法中的s也指向stringpool中"abc"对象;
* (3)changeString方法中执行s = "cba",会在常量池中创建"cba"对象,方法中的s并指向"cba"对象,外部的s仍指向"abc"对象
*/
String s = "abc";
test.changeString(s);
System.out.println(s); // "abc"
}
}

class Point {
int x;
int y;

public Point(int x, int y) {
this.x = x;
this.y = y;
}
}


public class PrivateTest {
private String name = "eg366";
private Date time = new Date();

public String getName() {
return name;
}

public Date getTime() {
return time;
}

public static void main(String[] args) {
/* 在外部对PrivateTest对象中time对象进行修改 */
PrivateTest test = new PrivateTest();
Date time = test.getTime();
Calendar calendar = GregorianCalendar.getInstance();
calendar.set(2000, 1, 1);
time.setTime(calendar.getTime().getTime());
System.out.println("time:"
+ new SimpleDateFormat("yyyy-MM-dd").format(test.getTime()));
}
}


四、final的成员变量

/**
* 对于final类型的成员变量的初始化方式
* (1)声明变量时直接赋值
* (2)在构造方法中完成赋值,如果一个类中有多个构造方法,就要保证在每个构造方法中都要完成对该final类型变量的初始化工作
* 如果变量是statis的,需要在声明的时候就赋值
* "The blank final field a may not have been initialized"
*/
public class FinalTest {

final int a;

public FinalTest() {
a = 1;
}

public FinalTest(String name) {
a = 2;
}
}


五、初始化顺序

/**
* 变量初始化顺序 (1)父静态方法块;(2)子静态方法块;(3)父构造方法;(4)子构造方法
*/
public class OrderTest {
public static void main(String[] args) {
new Child();
}
}

class Parent {
static String name = "hello";
static {
System.out.println("parent static block");
}

public Parent() {
System.out.println("parent constructor");
}
}

class Child extends Parent {
static String childName = "world";
static {
System.out.println("child static block");
}

public Child() {
System.out.println("child constructor");
}
}


六、override覆写

/**
* 方法的override覆写
* (1)子类中的方法与父类中的方法有相同的返回类型,相同的方法名称,相同的参数列表
* (2)子类中方法的访问级别不能低于父类中该方法的访问级别
* (3)子类中方法抛出的异常范围不能大于父类中该方法抛出的异常范围
*/
public class OverrideTest {

public static void main(String[] args) {

}
}

class Parent2 {
void print() throws NullPointerException {
System.out.println("parent");
}
}

class Child2 extends Parent2 {
/* 子类中方法抛出的异常不能大于父类中抛出的异常 */
// void print() throws Exception {
// void print() throws NoSuchMethodException {
@Override
void print() throws NullPointerException {
System.out.println("child");
}
}


七、final、abstract

/**
* 一个类不能既是abstract又是final的
*(1)abstract的类,不能被实例化,必须通过继承的子类来实例化
*(2)final类不能有子类
* 二者含义冲突,所以。。。
*/
//public abstract final class AbstractFinalTest {	//error
//public abstract class AbstractFinalTest {	//ok
public final class AbstractFinalTest {

/* 为何一般情况针对一个final终态的成员变量,都声明为static;为了节省内存,对于10个实例化的类对象,statis的成员变量只有一份 */
public static final String str = "abc";
}


八、reflect

/**
* 反射
* 获得某个类对应的class对象的方式
* (1)使用类的.class语句
* (2)使用类的对象的.getClass()方法
* (3)通过Class对象的.forName()方法
* (4)对于包装类,可以通过.TYPE语法方式;例:Integer.TYPE
*/
public class ReflectionTest {
public static void main(String[] args) throws Exception {
Class<PrivateTest> c = (Class<PrivateTest>) Class
.forName("com.test.PrivateTest");
PrivateTest pt = c.newInstance();
Field f = c.getField("name");
/* 忽略private等范围的限制,可对private属性进行修改 */
f.setAccessible(true);
f.set(pt, "lal366");
System.out.println(pt.getName());
}
}


九、泛型

public class FanxingTest {

public void method1(List<Exception> list) {
}

public void method2() {
method1(new ArrayList<Exception>());
/* 编译不通过 */
// method1(new ArrayList<RuntimeException>());
// method1(new LinkedList<RuntimeException>());
}

public void method3(List<? extends Exception> list) {
}

public void method4() {
method3(new ArrayList<Exception>());
method3(new ArrayList<RuntimeException>());
method3(new LinkedList<RuntimeException>());
}

/**
* List<?>等价于List<? extends Object>
*/
public void method5(List<?> list) {
}

public void method6() {
method5(new ArrayList<Exception>());
method5(new ArrayList<Point>());
method5(new LinkedList<Date>());
}
}


十、&,&&

public class YuTest {

public static void main(String[] args) {
test01();
test02();
test03();
}

private static void test01() {
int a = 3;
int b = 5;
System.out.println(a & b); // 位进行“与运算”
}

private static void test02() {
int a = 1;
int b = 2;
/* 短路与,第一个为false,后边的不会执行 */
if ((a == 2) && ((b = 3)) == 3) {
System.out.println("is true");
}
System.out.println("a:" + a + ";b:" + b);
}

private static void test03() {
int a = 1;
int b = 2;
/* 普通与逻辑运算,每个表达式都会计算 */
if ((a == 2) & ((b = 3)) == 3) {
System.out.println("is true");
}
System.out.println("a:" + a + ";b:" + b); // a:1;b:3
}
}


十一、Exception

/**
* java中异常分两类
* 1、check exception:必须捕获
* 2、unchecked exception(runtime exception,继承RuntimeException):可以不捕获
*/
public class ExceptionTest {

public void doSomething() throws NullPointerException {
System.out.println("do something");
}

public static void main(String[] args) {
ExceptionTest test = new ExceptionTest();
/* 方法中抛出的如果是运行时异常,可以不进行捕获 */
test.doSomething();
}
}


十二、内部类

/**
* 内部类
* (1)静态内部类;(2)成员内部类;(3)局部内部类;(4)匿名内部类
*/
public class Test01 {

@SuppressWarnings("deprecation")
private String get(Date date) {
return date.toLocaleString();
}

public static void main(String[] args) {
Test01 t = new Test01();
System.out.println(t.get(new Date()));
/* 匿名内部类;该类一定是继承了某个父类或者实现了某个接口 */
System.out.println(t.get(new Date() {
@Override
public String toLocaleString() {
return "hello world";
}
}));
}
}


十三、ArrayList、LinkedList、Vector

/**
* (1)ArrayList(jdk1.2)底层代码是采用数组实现呢(是Object类型的数组。源码中elementData全局变量)
* (2)当调用无参构造方法时,会调用"public ArrayList(int initialCapacity)"构造方法,默认数组长度是10。
* (3)在调用add方法时,会先判断当前数组的length是否满足add后数组中对象的总个数。
*  如果不满足会调用"Arrays.copyOf(elementData, newCapacity)"创建一个新长度的数组
* (4)Vector(jdk1.0)的底层也是使用Object数组来实现的;与ArrayList的区别:vector是同步的,线程安全的。
* (5)StringBuilder(jdk1.5)与StringBuffer(jdk1.0)的区别,StringBuffer是同步的,线程安全的
* (6)LinkedList(jdk1.2)的底层数据结构式"双向循环链表"(双向:每个元素有previous和next两个属性;循环:最后一个元素的next指向第一个元素)
* (7)对于ArrayList,查找速度快,删除和在数组中增加元素速度慢(由数组的特点决定的;删除list中第n个,第(n+1)到数组.length的元素都需要在数组中向前走一个index)。
* (8)对于LinkedList,查找速度慢,删除和在集合中增加元素速度快。(由双向循环链表的特点决定。只需对操作元素和前后元素的previous、next属性进行修改即可)
*/
public class ArrayListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();

Vector<String> vector = new Vector<String>();

list = new LinkedList<String>();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: