10-24Java刷题

1、下面程序执行后b的值是(true)

Integer integ=new Integer(9);
boolean b=integ instanceof Object;

解析:instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例,
而Object是所有类的父类。
2、ArrayList和LinkedList均实现了List接口;ArrayList的访问速度比LinkedList快;HashMap实现Map接口,它允许任何类型的键和值对象;ArrayList是基于数组实现的,所以查询快,增删慢;LinkedList是基于链表实现的,所以查找慢,增删快。
3、选项中哪一行代码可以替换//add code here而不产生编译错误

public abstract class MyClass{
    public int constInt=5;
    //add code here
    public void method(){
    }
}

在这里插入图片描述
解析:A是抽象方法,抽象类可以包含抽象方法,也可以不包含,实现重载。
B 在类中不能constInt=consInt+5
C 返回值不能作为重载的依据
D 有方法体的不能作为抽象函数
4、HttpServletRequest类主要处理:
(1)读取和写入HTTP头标
(2)取得和设置cookies
(3)取得路径信息
(4)标识HTTP会话
5、关于Float,下列说法错误的是(C)
A.Float是一个类
B.Float在java.lang包中
C.Float a=1.0是正确的赋值方法
D.Float a=new Float(1.0)是正确的赋值方法
解析:(1)Float是类,float不是类。
(2)查看JDK源码就可以发现Byte,Character,Short,Integer,Long,Float,Double,Boolean都在java.lang包中。
(3)Float正确复制方式是Float f=1.0f,若不加f会被识别成double型,double无法向float隐式转换。
(4)Float a= new Float(1.0)是正确的赋值方法,但是在1.5及以上版本引入自动装箱拆箱后,会提示这是不必要的装箱的警告,通常直接使用Float f=1.0f。
6、运行下面代码,输出的结果是

class A{
 
public A() {

System.out.println("class A");

}

{ System.out.println("I'm A class"); }

static  { System.out.println("class Astatic");  }

}

public class B extends A {

public B(){

System.out.println("class B");

}

{ System.out.println("I'm B class");  }

static { System.out.println("class B staic");  }


public static void main(String[] args){

new B();

}

}

答案:
class A static
class B static
I’m A class
class A
I’m B class
class B
B继承A new B会
(1)把A的静态的执行完 执行B的静态的
(2)再执行A的初始化代码块,构造函数
(3)再执行B的初始化代码块,构造函数
7、如下代码,执行test()函数后,屏幕打印结果为-128 127

public class Test2
{
     public void add(Byte b)
     {
        b=b++;
      }
      public void teat()
      {
         Byte a=127;
         Byte b=127;
         add(++a);
         System.out.print(a+"  ");
         add(b);
         System.out.print(b+" ");
        }
   }
        

解析:public void add(Byte b){ b=b++; } 这里涉及java的自动装包/自动拆包(AutoBoxing/UnBoxing) Byte的首字母为大写,是类,看似是引用传递,但是在add函数内实现++操作,会自动拆包成byte值传递类型,所以add函数还是不能实现自增功能。也就是说add函数只是个摆设,没有任何作用。 Byte类型值大小为-128~127之间。 add(++a);这里++a会越界,a的值变为-128 add(b); 前面说了,add不起任何作用,b还是127。
8、检查程序,是否存在问题,如果存在,支出问题所在;如果不存在,说明输出结果。

package algorithms.com.guan.javajicu;
public class Inc{
   public static void main(String[] args){
      Inc inc=new Inc();
      int i=0;
      inc.fermin(i);
      i=i++;
      System.out.println(i);
    }
    void fermin(int i){
       i++;
     }
  }

解析:输出0
Java虚拟机栈(JVM Stack)描述的是Java方法执行的内存模型,而JVM内存模型是基于“栈帧”的,每个栈帧中都有 局部变量表 和 操作数栈 (还有动态链接、return address等),那么JVM是如何执行这个语句的呢?通过javap大致可以将上面的两行代码翻译成如下的JVM指令执行代码。
0: iconst_0
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_1
7: iload_1

接下来分析一下JVM是如何执行的:
第0:将int类型的0入栈,就是放到操作数栈的栈顶
第1:将操作数栈栈顶的值0弹出,保存到局部变量表 index (索引)值为1的位置。(局部变量表也是从0开始的,0位置一般保存当前实例的this引用,当然静态方法例外,因为静态方法是类方法而不是实例方法)
第2:将局部变量表index 1位置的值的副本入栈。(这时局部变量表index为1的值是0,操作数栈顶的值也是0)
第3:iinc是对int类型的值进行自增操作,后面第一个数值1表示,局部变量表的index值,说明要对此值执行iinc操作,第二个数值1表示要增加的数值。(这时局部变量表index为1的值因为执行了自增操作变为1了,但是操作数栈中栈顶的值仍然是0)
第6:将操作数栈顶的值弹出(值0),放到局部变量表index为1的位置(旧值:1,新值:0),覆盖了上一步局部变量表的计算结果。
第7:将局部变量表index 1位置的值的副本入栈。(这时局部变量表index为1的值是0,操作数栈顶的值也是0)

总结:从执行顺序可以看到,这里第1和第6执行了2次将0赋值给变量i的操作(=号赋值),i++操作是在这两次操作之间执行的,自增操作是对局部变量表中的值进行自增,而栈顶的值没有发生变化,这里需要注意的是保存这个初始值的地方是操作数栈而不是局部变量表,最后再将栈顶的值覆盖到局部变量表i所在的索引位置中去。

有兴趣的同学可以去了解一下JVM的栈帧(Stack Frame)

关于第二个陷阱(为什么 fermin方法没有影响到i的值 )的解答看下面。
inc.fermin(i);
(1)java方法之间的参数传递是 值传递 而不是 引用传递
(2)每个方法都会有一个栈帧,栈帧是方法运行时的数据结构。这就是说每个方法都有自己独享的局部变量表。(更严谨的说法其实是每个线程在执行每个方法时都有自己的栈帧,或者叫当前栈帧 current stack frame)
(3)被调用方法fermin()的形式参数int i 实际上是调用方法main()的实际参数 i 的一个副本。
(4)方法之间的参数传递是通过局部变量表实现的,main()方法调用fermin()方法时,传递了2个参数:
第0个隐式参数是当前实例(Inc inc = new Inc(); 就是inc引用的副本,引用/reference 是指向对象的一个地址,32位系统这个地址占用4个字节,也就是用一个Slot来保存对象reference,这里传递的实际上是reference的一个副本而不是 reference本身 );
第1个显示参数是 i 的一个副本。所以 fermin()方法对 i 执行的操作只限定在其方法独享或可见的局部变量表这个范围内,main()方法中局部变量表中的i不受它的影响;
如果main()方法和fermin()方法共享局部变量表的话,那答案的结果就会有所不同。 其实你自己思考一下,就会发现, JVM虚拟机团队这么设计是有道理的。
9、数组越界、指定URL不存在、使用throw语句抛出可以引发异常
throws出现在方法头,throw出现在方法体;throws表示出现异常的一种可能性,并不一定会发生异常;throw则是泡池了异常,执行throw则一定是抛出某种异常;两者都是消极的异常处理方式,只是抛出或者可能抛出异常,是不会由函数处理,真正的处理异常由它的上层调用处理。
10、run()方法用来执行线程体中具体的内容
start()方法用来启动线程对象,使其进入就绪状态
sleep()方法用来使线程进入睡眠状态
suspend()方法用来使线程挂起,要通过resume()方法使其重新启动

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值