abstract方法可以直接调用?
来源:互联网 发布:网络统考英语在线" 编辑:程序博客网 时间:2024/06/03 00:33
先看一段代码:
import java.io.IOException;public class RuntimeTest {public static void main(String[] args) throws IOException, InterruptedException{Process p=Runtime.getRuntime().exec("notepad.exe");p.waitFor();System.out.println("end!");}
查看文档,发现Process类的waitFor()方法是一个abstract方法。可是为什么可以直接调用啊???
恩,直觉上想,应该是下面这行代码,实际返回的是Process类的一个子类,在子类中重写了waitFor()方法。
Runtime.getRuntime().exec("notepad.exe");那实际情况呢?我们查看下源码JDK1.5:
Runtime的源码,重载了好几个exec方法,但所有的exec方法都是调用下面这个方法来实现的。
public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException { return new ProcessBuilder(cmdarray) .environment(envp) .directory(dir) .start(); }
那我们再来查看ProcessBuilder的start方法源码:
public Process start() throws IOException { // Must convert to array first -- a malicious user-supplied // list might try to circumvent the security check. String[] cmdarray = command.toArray(new String[command.size()]); cmdarray = cmdarray.clone(); for (String arg : cmdarray) if (arg == null) throw new NullPointerException(); // Throws IndexOutOfBoundsException if command is empty String prog = cmdarray[0]; SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkExec(prog); } String dir = directory == null ? null : directory.toString(); try { return ProcessImpl.start(cmdarray, environment, dir, redirects, redirectErrorStream); } catch (IOException | IllegalArgumentException e) { String exceptionInfo = ": " + e.getMessage(); Throwable cause = e; if ((e instanceof IOException) && security != null) { // Can not disclose the fail reason for read-protected files. try { security.checkRead(prog); } catch (AccessControlException ace) { exceptionInfo = ""; cause = ace; } } // It's much easier for us to create a high-quality error // message than the low-level C code which found the problem. throw new IOException( "Cannot run program \"" + prog + "\"" + (dir == null ? "" : " (in directory \"" + dir + "\")") + exceptionInfo, cause); } }可以看到,返回的是:ProcessImpl.start(cmdarray,environment,dir, redirects, redirectErrorStream);,那就再查看ProcessImpl类的源码。
package java.lang;import java.io.IOException;import java.io.File;import java.io.InputStream;import java.io.OutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.FileDescriptor;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.lang.ProcessBuilder.Redirect;import java.security.AccessController;import java.security.PrivilegedAction;import java.util.ArrayList;import java.util.regex.Matcher;import java.util.regex.Pattern;/* This class is for the exclusive use of ProcessBuilder.start() to * create new processes. * * @author Martin Buchholz * @since 1.5 */final class ProcessImpl extends Process {<pre name="code" class="java">/**中间部分代码省略*/// System-dependent portion of ProcessBuilder.start() static Process start(String cmdarray[], java.util.Map<String,String> environment, String dir, ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException { String envblock = ProcessEnvironment.toEnvironmentBlock(environment); FileInputStream f0 = null; FileOutputStream f1 = null; FileOutputStream f2 = null; try { long[] stdHandles; if (redirects == null) { stdHandles = new long[] { -1L, -1L, -1L }; } else { stdHandles = new long[3]; if (redirects[0] == Redirect.PIPE) stdHandles[0] = -1L; else if (redirects[0] == Redirect.INHERIT) stdHandles[0] = fdAccess.getHandle(FileDescriptor.in); else { f0 = new FileInputStream(redirects[0].file()); stdHandles[0] = fdAccess.getHandle(f0.getFD()); } if (redirects[1] == Redirect.PIPE) stdHandles[1] = -1L; else if (redirects[1] == Redirect.INHERIT) stdHandles[1] = fdAccess.getHandle(FileDescriptor.out); else { f1 = newFileOutputStream(redirects[1].file(), redirects[1].append()); stdHandles[1] = fdAccess.getHandle(f1.getFD()); } if (redirects[2] == Redirect.PIPE) stdHandles[2] = -1L; else if (redirects[2] == Redirect.INHERIT) stdHandles[2] = fdAccess.getHandle(FileDescriptor.err); else { f2 = newFileOutputStream(redirects[2].file(), redirects[2].append()); stdHandles[2] = fdAccess.getHandle(f2.getFD()); } } return new ProcessImpl(cmdarray, envblock, dir, stdHandles, redirectErrorStream); } finally { // In theory, close() can throw IOException // (although it is rather unlikely to happen here) try { if (f0 != null) f0.close(); } finally { try { if (f1 != null) f1.close(); } finally { if (f2 != null) f2.close(); } } }
/*
*中间部分代码省略
*/
public int waitFor() throws InterruptedException { waitForInterruptibly(handle); if (Thread.interrupted()) throw new InterruptedException(); return exitValue(); } private static native void waitForInterruptibly(long handle);}可以看出,ProcessImpl类是Process类的一个子类,start方法最后返回了一个ProcessImpl对象。而且ProcessImpl重写了waitFor方法。
0 0
- abstract方法可以直接调用?
- java的静态方法可以直接用类名调用的理解
- java中为什么类名可以直接调用静态方法?
- java的静态方法可以直接用类名调用的理解
- 类可以直接调用静态方法,对象调用非静态方法
- 调用webview拨打电话----封装好的方法直接调用就可以
- java类的构造方法可以直接调用该类中已有的方法。
- 页面调用方法弹出企业QQ联系客服的方法,可以直接复制过去使用
- 《Java编程思想》中为什么可以直接用方法名调用静态方法?
- static方法可以直接从普通方法(regular method)中调用,但是普通方法不能直接从static方法中调用,为什么?
- 调用静态方法是不能用this关键字的。直接使用类名就可以了
- Java中可以直接调用类中静态方法,不用实例化
- C#可以直接调用的Win32API
- 可以直接调用构造函数吗??
- 静态方法不能直接调用实例方法和变量,但可以间接调用(即在静态方法中创建类的实例,然后调用)
- js 直接调用webservice 方法
- 类方法的直接调用
- Abstract方法不能用final,static修饰非abstract方法在abstract类中可以用fina
- HDU 4493
- delphi编程里的bool跟boolean类型有什么区别
- ubuntu下使用java、javac命令行编译工程
- struts2中的命名空间
- PRIMARY KEY、UNIQUE KEY、INDEX区别
- abstract方法可以直接调用?
- mfc 窗口控件全屏显示
- vmware虚拟机迁移导致的eth0消失问题
- 如何登陆google
- 实现Oracle 10g 每天自动备份数据
- java 时间处理
- Android so动态库开发完成!
- Authentic Louis Vuitton Sunglasses JCVxT
- GridView1_RowDataBound中能不能得到ItemTemplate中Label控件绑定的Text值??