System.in.read()问题

来源:http://zhidao.baidu.com/question/74164319

 

Q:

System.in.read()中in是一个字段即静态常量(JAVA帮助文档中:public static final InputStream in),那么
问题一:in可以使用InputStream中的所有方法么?如果可以就是说静态常量可以引用该类的所有方法。但是我调试的时候静态常量只能引用该类的静态方法。
例如:
class A{
     public static  void test(){
     System.out.println("HA HA");
     }
}
class B{
     public static A printTest;
}

class Run
{
     public static void main(String[] args)
     {
           B.printTest.test();
     }
}

把class A中test方法的static去掉或者改为别的就会出错。

问题二:在InputStream中read()方法在JAVA帮助文档中是这样的:abstract int read()   抽象方法不是没有方法体么?那么是如何执行输入功能的?

A:
楼主听我来为你分析一下:
in在System类中的声明方式为“public static final InputStream in”,也就是说in是一个static的field,即in属于System这个类,而不属于某个System类的对象,实际是因为System是用final修饰的,所以你也不可能用new关键字来创建出一个System类的对象。所以,要访问in这个InputStream类型的对象,你只能用System.in这样的方式,而且用System.in这样的方式访问到的就是一个普通的InputStream类型的对象,你可以调用InputStream类里的所有实例方法(没有static修饰的方法),也可以调用InputStream类里的所有类方法(但是用对象来调用类方法是不建议这样子操作的)。你举的例子中main方法中的"B.printTest.test();"一句我们来分析一下,因为B类中的A类型对象printTest用static修饰了,所以访问它(printTest)的时候要用"B.printTest"这样的方式,而这样的方式得到的就是一个普通的A类型的对象,所以它可以访问A类中的所有实例方法和静态方法,当你写的A类中的test方法前面有static修饰时,表示test是一个静态方法,所以要访问这个test方法最好是通过A.test()这样的方式,但是java语言并不强制要求这一点,也就是说你也可以通过任何A类的对象来访问test方法,比如你现在代码中写的"B.printTest.test()"就是这样,因为刚才说了"B.printTest"就是一个A类的对象。所以,你这样写是可以执行的,但是不好。如果你把test方法前的static去掉,那就符合我们说的“实例方法要通过类的具体的一个对象来访问”这一个原则了,所以把test方法前面的static去掉是可以的。这样子我们编译的过程没有错,但是执行的时候就会出错,为什么呢?因为你目前在B类中声明printTest时候没有为它实例化,换句话说这个时候printTest是null,所以当然会出错了,你只要把它实例化一下就可以了,如下:

================================

class A {
    public void test() {
    System.out.println("HA HA");
    }
}

class B {
    public static A printTest = new A();
}

class Run {
    public static void main(String[] args) {
           B.printTest.test();
    }
}

================================

第二个问题:
InputStream类中的read方法是abstract的,但是我们通过System.in得到的不是一个直接的InputStream对象,InputStream类本身为abstract的,你也不可能创建出这个类的一个对象来,实际上,我们通过System.in得到的是某一个InputStream的子类的对象,这就是java中多态的概念,即父类的变量可以引用子类的对象。查看一下java的源文件就可以知道这个in是通过native code得到的,所以你不用过分关心它到底是什么类型的,只要知道它就是一个InputStream类的子类的对象,我们可以通过它使用所有InputStream类的方法就可以了。

-------------------------------------------------------------

问题一:
我们从JDK中可以看到 其实in只是System 中的一个字段,就是一条静态属性,所以使用它的时候和我们自定义的类中使用静态属性的使用方法是一样的,即只能由静态方法调用静态属性,因为in不是System的对象所以不存在调用System中的方法的情况.在你说的例子中因为A的对象printTest是静态对象所以可以直接用B类名调用,所以他只能调用静态方法或者由静态方法调用,所以方法test必须是静态方法,如果你要把test中的static去掉,那在class B中就对printTest的定义也就必须去掉static.如果是在不薄白可以找些JAVA基础的书,每本里都会有关于static的使用说明的.
问题二:
抽象的方法是没有方法实体的,要使用它就必须由他的子类来重载,这是java的多台的一个表现,我们在使用对象调用一个抽象方法的时候其实并不是调用它本身,其实是调用它的子类中重载过的方法,比如我们一般使用inputstream的对象调用read方法,但是实际上我们调用的都是inputstream的子类,比如Fileinputstream等中的read()方法,因为在他的那些子类中read()方法都有实体的,但是内容不一样,这样一个方法在不同的类中表现的内容不一样,这样也可以很好的体现java的多态性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值