类继承的问题。。。。 看不懂源码,求教。

gdy1039 2004-12-28 06:07:05
import java.io.*;
import java.net.*;
public class GetHttp{
public static void main(String[] args) throws Exception{
URL targetUrl = null;
HttpURLConnection httpUrl = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
byte[] buf = new byte[1024];
int size = 0;
System.out.println(0 + args[0]);
System.out.println(1 + args[1]);
//System.out.println(args[2]);
if(args.length != 2){
System.out.println("usage: GetHttp targeturl targetfile");
return;
}
targetUrl=new URL(args[0]);
httpUrl = (HttpURLConnection) targetUrl.openConnection();
//httpUrl = new HttpURLConnection(new URL(args[0]));
httpUrl.connect();       //***这一行***
bis =new BufferedInputStream(httpUrl.getInputStream());
fos = new FileOutputStream(args[1]);
System.out.println("正从[" + args[0] + "]下载文件,并保存为[" + args[1] + "]");
while( (size = bis.read(buf)) != -1){
fos.write(buf,0,size);
}
fos.close();
bis.close();
httpUrl.disconnect();
}
}
//:~
请问其中的httpUrl.connect();这行里的connect是使用那个类的函数,因为httpUrlConnect这个类的定义如下:
public abstract class HttpURLConnectionextends URLConnection
然后URLConnection也是抽像类,它的connect定义也是抽像的,那到底这个函数是在那里实现的呢?
abstract void connect()
...全文
360 点赞 收藏 20
写回复
20 条回复
gdy1039 2005年01月17日
如果不是静态的,就必需先创建对象,然后再调用工厂方法。但对像又是由工厂方法创建的,这不是死循环了吗?
回复 点赞
wangsheng1028 2005年01月16日
工厂方法为什么一定要静态的呀
这个好像不对哦,一般工厂方法都设计为单例倒是真的。
回复 点赞
gdy1039 2005年01月16日
我还是不知道handler factory是什么
回复 点赞
kerosun 2005年01月04日
mark
回复 点赞
gdy1039 2005年01月04日
To: lxpbuaa(桂枝香在故国晚秋)
你在回答我handler factory的问题?请正面并详细的回答好吗?就这样丢出一堆东西,我们菜菜不一定明的呀,你看看我是一个三角的呀,不像你三个星呀。

之前我写的方法有点错,现在改正:
public class Generator{
private int i;
private Generator(int j){ i=j }
public static Generator getGenerator(int k){ //这个函数就是工厂方法
return Generator(k);
}
public static void main(String[] args){
......
}
}

工厂方法必需是静态的,否则无法调用。
回复 点赞
lxpbuaa 2005年01月03日
targetUrl.openConnection()返回了HttpURLConnection子类的对象,因此httpUrl.connect中connect实际是指targetUrl.openConnection实际返回的对象的connect

回复 点赞
classjava 2005年01月03日
mark
回复 点赞
gdy1039 2005年01月03日
工厂方法解释如下:
//Generator.java
public class Generator{
private int i;
private Generator(int j){ i=j }
public Generator getGenerator(int k){ //这个函数就是工厂方法
return Generator(k);
}
public static void main(String[] args){
......
}
}
上面的注解的方法就是工厂方法,它的作用是控制对像的产生,使得不是任何人都可以使用NEW产生该对像。

URI的解释如下:
URI是JAVA新加的元素,URL是它的子集。

我最近学到的知识就这么多,希望对大家有好处。
还差handler factory,不知有没有人明白?
回复 点赞
Mohooo 2004年12月31日
takecare(大厅) ( )

此人 so强
回复 点赞
ROBOT 2004年12月30日
分析这种代码有意思!

不明白:
在ULR.java中,
...
transient InetAddress hostAddress;

/**
* The URLStreamHandler for this URL.
*/
transient URLStreamHandler handler;
...

"transient"是干什么用的?
回复 点赞
IT老兵 2004年12月30日
public final class URL implements java.io.Serializable{...}

transient 意思就是序列化或者持久化后由这个关键字修饰的变量将不再被保存,从而变成null或者0。
回复 点赞
treeroot 2004年12月29日
斑竹真热情
回复 点赞
IT老兵 2004年12月29日
不好意思,写错了一些。
“...由于为了能够处理不同的http协议所以引入了handler factory从而变的比较复杂了...”
^^^^^^^^^
应该是URL所支持的不同的协议,http只是其中的一种,呵呵。
回复 点赞
fog628 2004年12月29日
mark
回复 点赞
gdy1039 2004年12月29日
很多明词都不明白,我看还是需要把基础再打好一点。
handler factory
工厂方法
URI
这些都不清楚。

谢谢版主热情解答,等我明白这个问题后再结这贴子。
回复 点赞
night__cat 2004年12月29日
谁是斑竹?
回复 点赞
launch401 2004年12月28日
HttpURLConnection httpUrl = (HttpURLConnection) targetUrl.openConnection();
openConnection()是一个工厂方法,targetUrl.openConnection():返回的肯定是一个HttpURLConnection 的具体子类,通过工厂方法就封装了这个具体子类的创建,而只给client一个抽象类。
回复 点赞
IT老兵 2004年12月28日
好,接下来我们看看connect()到底做了什么?
在URL类中,会根据请求来分析到底是什么协议(简单来说http://开头的是http协议,ftp://是ftp协议,如果有兴趣请参考rfc关于url的说明)从而加载相应的实现类,比如http的话,就会实例化"sun.net.www.protocol.http.HttpURLConnection",而那个HttpURLConnection正好就是
public class HttpURLConnection extends java.net.HttpURLConnection {...}。
这样就清楚了,connect其实就是sun给出的一个实现罢了。
一下给出jdk1.5.0中的实现:
// overridden in HTTPS subclass

public void connect() throws IOException {
plainConnect();
}

protected void plainConnect() throws IOException {
if (connected) {
return;
}
// try to see if request can be served from local cache
if (cacheHandler != null && getUseCaches()) {
try {
URI uri = ParseUtil.toURI(url);
if (uri != null) {
cachedResponse = cacheHandler.get(uri, getRequestMethod(), requests.getHeaders(EXCLUDE_HEADERS));
if ("https".equalsIgnoreCase(uri.getScheme())
&& !(cachedResponse instanceof SecureCacheResponse)) {
cachedResponse = null;
}
if (cachedResponse != null) {
cachedHeaders = mapToMessageHeader(cachedResponse.getHeaders());
cachedInputStream = cachedResponse.getBody();
}
}
} catch (IOException ioex) {
// ignore and commence normal connection
}
if (cachedHeaders != null && cachedInputStream != null) {
connected = true;
return;
} else {
cachedResponse = null;
}
}
try {
/* Try to open connections using the following scheme,
* return on the first one that's successful:
* 1) if (instProxy != null)
* connect to instProxy; raise exception if failed
* 2) else use system default ProxySelector
* 3) is 2) fails, make direct connection
*/

if (instProxy == null) { // no instance Proxy is set
/**
* Do we have to use a proxy?
*/
ProxySelector sel = (ProxySelector)
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
return ProxySelector.getDefault();
}
});
Proxy p = null;
if (sel != null) {
URI uri = sun.net.www.ParseUtil.toURI(url);
Iterator<Proxy> it = sel.select(uri).iterator();
while (it.hasNext()) {
p = it.next();
try {
if (!failedOnce) {
http = getNewHttpClient(url, p, connectTimeout);
http.setReadTimeout(readTimeout);
} else {
// make sure to construct new connection if first
// attempt failed
http = getNewHttpClient(url, p, connectTimeout, false);
http.setReadTimeout(readTimeout);
}
break;
} catch (IOException ioex) {
if (p != Proxy.NO_PROXY) {
sel.connectFailed(uri, p.address(), ioex);
if (!it.hasNext()) {
// fallback to direct connection
http = getNewHttpClient(url, null, connectTimeout, false);
http.setReadTimeout(readTimeout);
break;
}
} else {
throw ioex;
}
continue;
}
}
}
} else {
if (!failedOnce) {
http = getNewHttpClient(url, instProxy, connectTimeout);
http.setReadTimeout(readTimeout);
} else {
// make sure to construct new connection if first
// attempt failed
http = getNewHttpClient(url, instProxy, connectTimeout, false);
http.setReadTimeout(readTimeout);
}
}

ps = (PrintStream)http.getOutputStream();
} catch (IOException e) {
throw e;
}
// constructor to HTTP client calls openserver
connected = true;
}

回复 点赞
IT老兵 2004年12月28日
呵呵,gdy1039 (大勇) 够心细的。
不过你刚好碰到了一块硬骨头,这里的继承关系由于为了能够处理不同的http协议所以引入了handler factory从而变的比较复杂了。呵呵。

首先看看
public abstract class URLConnection
extends Object
The abstract class URLConnection is the superclass of all classes that represent a communications link between the application and a URL. Instances of this class can be used both to read from and to write to the resource referenced by the URL. In general, creating a connection to a URL is a multistep process:


openConnection() connect()
Manipulate parameters that affect the Interact with the resource;
connection to the remote resource. query header fields and contents.
---------------------------->
time
1、The connection object is created by invoking the openConnection method on a URL.
2、The setup parameters and general request properties are manipulated.
3、The actual connection to the remote object is made, using the connect method.
4、The remote object becomes available. The header fields and the contents of the remote object can be accessed.

由此表明真正的连接是openConnection(),这正是URL类的方法。
所以很有趣的是如果你对于协议支持要求不高的话,你完全可以注释掉
// httpUrl.connect();//***这一行***/
而结果基本上不会有什么差别。
回复 点赞
虎叔 2004年12月28日
这就是将实现封装起来的例子啊!

一般你不用关心内部是如何实现的。
回复 点赞
发动态
发帖子
Java SE
创建于2007-09-28

3.4w+

社区成员

30.7w+

社区内容

Java 2 Standard Edition
社区公告
暂无公告