目录
题一
知识点:继承
class C {
C() {
System.out.print("C");
}
}
class A {
C c = new C();
A() {
this("A");
System.out.print("A");
}
A(String s) {
System.out.print(s);
}
}
class Niuke00 extends A {
Niuke00() {
super("B");
System.out.print("B");
}
public static void main(String[] args) {
new Niuke00();
}
}
代码运行结果:CBB
这道题很简单,注意类加载的大概顺序:父类的静态->子类的静态->父类的初始化块->父类的构造方法->子类的初始化块->子类的构造方法
题二
知识点:拆箱与装箱
通俗得讲,基本数据类型转化成包装类是装箱(如: int --> Integer)
包装类转化成基本数据类型就是拆箱 (如:Integer --> int)
包装类就是引用类型,基本数据类型就是值类型
public class Niuke02 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer i01=59;
int i02=59;
Integer i03=Integer.valueOf(59);
Integer i04=new Integer(59);
System.out.println(i01==i02);//true
System.out.println(i01==i03);//true
System.out.println(i03==i04);//false
System.out.println(i02==i04);//true
}
}
这题也很简单,i03==i04输出false的原因是:i04是通过new关键字创建,new Integer(59)会在堆内存中分配一个新的对象(值为59),而i04是在栈中引用堆中的数据,i03和i04在堆内存中不是同一个[地址],我们知道"=="不仅要比较值还要比较地址,故返回false。大致内存图如下:
题三
知识点:拆箱与装箱
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
System.out.println(c == d);//true
System.out.println(e == f);//false
System.out.println(c == (a+b));//true
System.out.println(c.equals(a+b));//true
System.out.println(g == (a+b));//true
System.out.println(g.equals(a+b));//false
该题中需要注意两个地方:1、"=="和"equals()"的区别,简单的讲,"=="不仅仅比较对象的值还要比较对象所在的内存地址是否相等,相等返回true,否则返回false;而"equals()"方法只比较值的大小 2、“e==f”输出false的原因是,整形池IntegerCache通过valueOf产生包装对象时,如果int参数在-128到127之间,则直接从整型池中获得对象,不在该范围的int类型则通过new生成包装对象。Jdk的源代码如下:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
题四
知识点:参数传递、局部变量
class Value {
public int i = 15;
}
public class Niuke03 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Niuke03 niuke03 = new Niuke03();
niuke03.first();
}
public void first() {
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
System.out.println(v.i);
}
public void second(Value v1, int i) {
i = 0;
v1.i = 20;
Value val = new Value();
v1 = val;
System.out.println(v1.i + " " + i);
}
}
上面的代码中为便于理解,我把原题中second的v改为了v1
注意Java由于没有指针这个概念,所以参数传递时都是值传递没有引用传递,可以通过传对象来达到引用传递的效果。在方法的形参中,传入的实参是值传递,只是将原来的地址值赋予了新的引用变量,即形参是一个新的引用变量。
在该题中注意调用first()和second()时的内存变化,相关内存如下:
代码最后运行结果:
15 0
20
题五
知识点:replaceAll()
String classFile = "com.jd.".replaceAll(".", "/")+"Myclass.class";
System.out.println(classFile);
代码运行结果:
///Myclass.class
题六
知识点:递归、位运算
public class Niuke05{
public static void main(String[] args) {
// TODO Auto-generated method stub
Niuke05 niuke5 = new Niuke05();
System.out.println(niuke5.Sum_Solution(7));
System.out.println(niuke5.addWithoutArithmetic(5,9));
//System.out.println(9<<2);
}
//不能用關鍵字求1+2+3+..+n的值
public int Sum_Solution(int n) {
int sum = n;
boolean flag = (n>0)&&((sum+=Sum_Solution(n-1))>0);
return sum;
}
//不能用+,-,*,/求兩個整數的和
int addWithoutArithmetic(int num1,int num2){
if(num2 == 0)
return num1;
int XORresult = num1 ^ num2;
int carry = (num1 & num2)<<1;
return addWithoutArithmetic(XORresult,carry);
}
}
这个需要基础非常好的才能解答,该代码也是参考别人的
题七
知识点:try-catch
public class Niuke07 {
private static String output = "";
public static void foo(int i){
try {
if(i==1){
throw new Exception();
}
} catch (Exception e) {
// TODO: handle exception
output +="2";
return;
}finally {
output += "3";
}
output += "4";
}
public static void main(String[] args) {
// TODO Auto-generated method stub
foo(0);
foo(1);
System.out.println(output);
}
}
第一次foo(0)没有捕获到异常,程序运行结束后output=“34”;第二次foo(1)后抛出了一个异常,程序执行catch()中的代码在return前output="342",然后程序并不会马上返回(需要执行完finally代码),即output="3423",此时程序已经返回不在执行output+="4"代码
代码运行结果为:
3423
题八
知识点:Java类中相关构造方法(代码块)加载顺序
class AAA {
static{
System.out.println("父類靜態代碼塊");
}
public AAA(){
System.out.println("父類構造方法");
}
{
System.out.println("父類構造塊");
}
}
public class Niuke08 extends AAA{
static{
System.out.println("子類靜態代碼塊");
}
public Niuke08(){
System.out.println("子類構造方法");
}
{
System.out.println("子類構造塊");
}
public static void main(String[] args) {
new Niuke08();
}
}
代码运行结果为:
父類靜態代碼塊
子類靜態代碼塊
父類構造塊
父類構造方法
子類構造塊
子類構造方法
题九
知识点:for()循环
public class Niuke09 {
static boolean foo(char c){
System.out.println(c);
return true;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0;
for(foo('A');foo('B')&&(i<2);foo('C')){
i++;
foo('D');
}
}
}
这个就是演示了for()循环的执行流程,结合概念很容易理解
代码执行结果:
A
B
D
C
B
D
C
B
题十
知识点:参数传递
public static void add3(Integer i){
int val=i.intValue();
val +=3;
i=new Integer(val);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer i=new Integer(0);
add3(i);
System.out.println(i.intValue());
}
参考题四,相关内存图就不画了
代码运行结果:
0
题十一
题目描述:编写程序实现字符串反转,比如原始字符串为"happyBirthday"反转后为"yadhtriByppah"
public String reverse(String originStr) {
if(originStr == null || originStr.length() <= 1)
return originStr;
String sub = originStr.substring(1);
char cha = originStr.charAt(0);
//System.out.println(sub+"--"+cha);
//遞歸
return reverse(sub)+cha;
}
注意subString()和charAt()方法
题十二
题目描述:输入年、月、日,计算算该天是这一年中的第几天
代码如下
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()){
int y = scanner.nextInt();
int m = scanner.nextInt();
int d = scanner.nextInt();
int[] a = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
int[] b = new int[]{31,29,31,30,31,30,31,31,30,31,30,31};
int count = 0;
if(isLeap(y)){
for(int i=0;i<m-1;i++)
count += b[i];
}else{
for(int i=0;i<m-1;i++)
count += a[i];
}
count += d;
System.out.println(count);
}
}
public static boolean isLeap(int y){
if(y%4==0&&y%100!=0||y%400==0)
return true;
else
return false;
}
题十三
题目描述:输入多种材料名称,输出一个数字表示完成所有料理需要多少种不同的材料。例如
输入:
BUTTER FLOUR
HONEY FLOUR EGG
输出:
4
代码如下:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
HashSet<String> set = new HashSet<>();
while (scanner.hasNext()){
String str = scanner.nextLine();
String[] arr = str.split(" ");
for(int i=0;i<arr.length;i++)
set.add(arr[i]);
}
System.out.println(set.size());
set.clear();
}
题十四
知识点:try-catch
static public void main(String[] args) {
System.out.println(test01.test());
}
static int test()
{
int x = 1;
try
{
return x;
} finally
{
++x;
}
}
代码运行结果是:
1
这个也是很经典的,因为finally总是在try-catch执行之后执行,而且一定是在return之前执行,更准确的说是在return中执行。finally执行也改变不了return的值,return的值已经是1了,finally执行完后x的值成了2。finally一定会执行?在return前还是return后执行?参考解析Java finally