applet是一種Java程序。它一般運行在支持Java的Web瀏覽器內(nèi)。因為它有完整的Java API支持,所以applet是一個全功能的Java應(yīng)用程序。
如下所示是獨立的Java應(yīng)用程序和applet程序之間重要的不同:
Java中applet類繼承了 java.applet.Applet類
Applet類沒有定義main(),所以一個 Applet程序不會調(diào)用main()方法,
Applets被設(shè)計為嵌入在一個HTML頁面。
當(dāng)用戶瀏覽包含Applet的HTML頁面,Applet的代碼就被下載到用戶的機器上。
要查看一個applet需要JVM。 JVM可以是Web瀏覽器的一個插件,或一個獨立的運行時環(huán)境。
用戶機器上的JVM創(chuàng)建一個applet類的實例,并調(diào)用Applet生命周期過程中的各種方法。
Applets有Web瀏覽器強制執(zhí)行的嚴(yán)格的安全規(guī)則,applet的安全機制被稱為沙箱安全。
applet需要的其他類可以用Java歸檔(JAR)文件的形式下載下來。
Applet的生命周期
Applet類中的四個方法給你提供了一個框架,你可以再該框架上開發(fā)小程序:
init: 該方法的目的是為你的applet提供所需的任何初始化。在Applet標(biāo)記內(nèi)的param標(biāo)簽被處理后調(diào)用該方法。
start: 瀏覽器調(diào)用init方法后,該方法被自動調(diào)用。每當(dāng)用戶從其他頁面返回到包含Applet的頁面時,則調(diào)用該方法。
stop:當(dāng)用戶從包含applet的頁面移除的時候,該方法自動被調(diào)用。因此,可以在相同的applet中反復(fù)調(diào)用該方法。
destroy: 此方法僅當(dāng)瀏覽器正常關(guān)閉時調(diào)用。因為applets只有在HTML網(wǎng)頁上有效,所以你不應(yīng)該在用戶離開包含Applet的頁面后遺漏任何資源.
paint: 該方法在start()方法之后立即被調(diào)用,或者在applet需要重繪在瀏覽器的時候調(diào)用。paint()方法實際上繼承于java.awt。
"Hello, World" Applet:
下面是一個簡單的Applet程序HelloWorldApplet.java:
import java.applet.*;
import java.awt.*;
public class HelloWorldApplet extends Applet
{
public void paint (Graphics g)
{
g.drawString ("Hello World", 25, 50);
}
}
這些import語句將以下類導(dǎo)入到我們的applet類中:
java.applet.Applet.
java.awt.Graphics.
沒有這些import語句,Java編譯器就識別不了Applet和Graphics類。
Applet 類
每一個applet都是java.applet.Applet 類的子類,基礎(chǔ)的Applet類提供了供衍生類調(diào)用的方法,以此來得到瀏覽器上下文的信息和服務(wù)。
這些方法做了如下事情:
得到applet的參數(shù)
得到包含applet的HTML文件的網(wǎng)絡(luò)位置
得到applet類目錄的網(wǎng)絡(luò)位置
打印瀏覽器的狀態(tài)信息
獲取一張圖片
獲取一個音頻片段
播放一個音頻片段
調(diào)整此 applet 的大小
除此之外,Applet類還提供了一個接口,該接口供Viewer或瀏覽器來獲取applet的信息,并且來控制applet的執(zhí)行。
Viewer可能是:
請求applet作者、版本和版權(quán)的信息
請求applet識別的參數(shù)的描述
初始化applet
銷毀applet
開始執(zhí)行applet
結(jié)束執(zhí)行applet
Applet類提供了對這些方法的默認(rèn)實現(xiàn),這些方法可以在需要的時候重寫。
"Hello,World"applet都是按標(biāo)準(zhǔn)編寫的。唯一被重寫的方法是paint方法。
Applet的調(diào)用
applet是一種Java程序。它一般運行在支持Java的Web瀏覽器內(nèi)。因為它有完整的Java API支持,所以applet是一個全功能的Java應(yīng)用程序。
<applet>標(biāo)簽是在HTML文件中嵌入applet的基礎(chǔ)。以下是一個調(diào)用"Hello World"applet的例子;
<html>
<title>The Hello, World Applet</title>
<hr>
<applet code="HelloWorldApplet.class" width="320" height="120">
If your browser was Java-enabled, a "Hello, World"
message would appear here.
</applet>
<hr>
</html>
注意: 你可以參照HTML Applet標(biāo)簽來更多的了解從HTML中調(diào)用applet的方法。
<applet>標(biāo)簽的屬性指定了要運行的Applet類。Width和height用來指定applet運行面板的初始大小。applet必須使用</applet>標(biāo)簽來關(guān)閉。
如果applet接受參數(shù),那么參數(shù)的值需要在標(biāo)簽里添加,該標(biāo)簽位于<applet>和</applet>之間。瀏覽器忽略了applet標(biāo)簽之間的文本和其他標(biāo)簽。
不支持Java的瀏覽器不能執(zhí)行<applet>和</applet>。因此,在標(biāo)簽之間顯示并且和applet沒有關(guān)系的任何東西,在不支持的Java的瀏覽器里是可見的。
Viewer或者瀏覽器在文檔的位置尋找編譯過的Java代碼,要指定文檔的路徑,得使用<applet>標(biāo)簽的codebase屬性指定。
如下所示:
<applet codebase="http://amrood.com/applets"
code="HelloWorldApplet.class" width="320" height="120">
如果applet所在一個包中而不是默認(rèn)包,那么所在的包必須在code屬性里指定,例如:
<applet code="mypackage.subpackage.TestApplet.class"
width="320" height="120">
獲得applet參數(shù)
下面的例子演示了如何使用一個applet響應(yīng)來設(shè)置文件中指定的參數(shù)。該Applet顯示了一個黑色棋盤圖案和第二種顏色。
第二種顏色和每一列的大小通過文檔中的applet的參數(shù)指定。
CheckerApplet 在init()方法里得到它的參數(shù)。也可以在paint()方法里得到它的參數(shù)。然而,在applet開始得到值并保存了設(shè)置,而不是每一次刷新的時候都得到值,這樣是很方便,并且高效的。
applet viewer或者瀏覽器在applet每次運行的時候調(diào)用init()方法。在加載applet之后,Viewer立即調(diào)用init()方法(Applet.init()什么也沒做),重寫該方法的默認(rèn)實現(xiàn),添加一些自定義的初始化代碼。
Applet.getParameter()方法通過給出參數(shù)名稱得到參數(shù)值。如果得到的值是數(shù)字或者其他非字符數(shù)據(jù),那么必須解析為字符串類型。
下例是CheckerApplet.java的梗概:
import java.applet.*;
import java.awt.*;
public class CheckerApplet extends Applet
{
int squareSize = 50;// 初始化默認(rèn)大小
public void init () {}
private void parseSquareSize (String param) {}
private Color parseColor (String param) {}
public void paint (Graphics g) {}
}
下面是CheckerApplet類的init()方法和私有的parseSquareSize()方法:
public void init ()
{
String squareSizeParam = getParameter ("squareSize");
parseSquareSize (squareSizeParam);
String colorParam = getParameter ("color");
Color fg = parseColor (colorParam);
setBackground (Color.black);
setForeground (fg);
}
private void parseSquareSize (String param)
{
if (param == null) return;
try {
squareSize = Integer.parseInt (param);
}
catch (Exception e) {
// 保留默認(rèn)值
}
}
該applet調(diào)用parseSquareSize(),來解析squareSize參數(shù)。parseSquareSize()調(diào)用了庫方法Integer. parseInt(),該方法將一個字符串解析為一個整數(shù),當(dāng)參數(shù)無效的時候,Integer.parseInt()拋出異常。
因此,parseSquareSize()方法也是捕獲異常的,并不允許applet接受無效的輸入。
Applet調(diào)用parseColor()方法將顏色參數(shù)解析為一個Color值。parseColor()方法做了一系列字符串的比較,來匹配參數(shù)的值和預(yù)定義顏色的名字。你需要實現(xiàn)這些方法來使applet工作。
指定applet參數(shù)
如下的例子是一個HTML文件,其中嵌入了CheckerApplet類。HTML文件通過使用標(biāo)簽的方法給applet指定了兩個參數(shù)。
<html>
<title>Checkerboard Applet</title>
<hr>
<applet code="CheckerApplet.class" width="480" height="320">
<param name="color" value="blue">
<param name="squaresize" value="30">
</applet>
<hr>
</html>
注意: 參數(shù)名字大小寫不敏感。
應(yīng)用程序轉(zhuǎn)換成Applet
將圖形化的Java應(yīng)用程序(是指,使用AWT的應(yīng)用程序和使用java程序啟動器啟動的程序)轉(zhuǎn)換成嵌入在web頁面里的applet是很簡單的。
下面是將應(yīng)用程序轉(zhuǎn)換成applet的幾個步驟:
編寫一個HTML頁面,該頁面帶有能加載applet代碼的標(biāo)簽。
編寫一個JApplet類的子類,將該類設(shè)置為public。否則,applet不能被加載。
消除應(yīng)用程序的main()方法。不要為應(yīng)用程序構(gòu)造框架窗口,因為你的應(yīng)用程序要顯示在瀏覽器中。
將應(yīng)用程序中框架窗口的構(gòu)造方法里的初始化代碼移到applet的init()方法中,你不必顯示的構(gòu)造applet對象,瀏覽器將通過調(diào)用init()方法來實例化一個對象。
移除對setSize()方法的調(diào)用,對于applet來講,大小已經(jīng)通過HTML文件里的width和height參數(shù)設(shè)定好了。
移除對 setDefaultCloseOperation()方法的調(diào)用。Applet不能被關(guān)閉,它隨著瀏覽器的退出而終止。
如果應(yīng)用程序調(diào)用了setTitle()方法,消除對該方法的調(diào)用。applet不能有標(biāo)題欄。(當(dāng)然你可以給通過html的title標(biāo)簽給網(wǎng)頁自身命名)
不要調(diào)用setVisible(true),applet是自動顯示的。
事件處理
Applet類從Container類繼承了許多事件處理方法。Container類定義了幾個方法,例如:processKeyEvent()和processMouseEvent(),用來處理特別類型的事件,還有一個捕獲所有事件的方法叫做processEvent。
為了響應(yīng)一個事件,applet必須重寫合適的事件處理方法。
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.applet.Applet;
import java.awt.Graphics;
public class ExampleEventHandling extends Applet
implements MouseListener {
StringBuffer strBuffer;
public void init() {
addMouseListener(this);
strBuffer = new StringBuffer();
addItem("initializing the apple ");
}
public void start() {
addItem("starting the applet ");
}
public void stop() {
addItem("stopping the applet ");
}
public void destroy() {
addItem("unloading the applet");
}
void addItem(String word) {
System.out.println(word);
strBuffer.append(word);
repaint();
}
public void paint(Graphics g) {
//Draw a Rectangle around the applet's display area.
g.drawRect(0, 0,
getWidth() - 1,
getHeight() - 1);
//display the string inside the rectangle.
g.drawString(strBuffer.toString(), 10, 20);
}
public void mouseEntered(MouseEvent event) {
}
public void mouseExited(MouseEvent event) {
}
public void mousePressed(MouseEvent event) {
}
public void mouseReleased(MouseEvent event) {
}
public void mouseClicked(MouseEvent event) {
addItem("mouse clicked! ");
}
}
如下調(diào)用該applet:
<html>
<title>Event Handling</title>
<hr>
<applet code="ExampleEventHandling.class"
width="300" height="300">
</applet>
<hr>
</html>
最開始運行,applet顯示 "initializing the applet. Starting the applet.",然后你一點擊矩形框,就會顯示"mouse clicked" 。
顯示圖片
applet能顯示GIF,JPEG,BMP等其他格式的圖片。為了在applet中顯示圖片,你需要使用java.awt.Graphics類的drawImage()方法。
如下實例演示了顯示圖片的所有步驟:
import java.applet.*;
import java.awt.*;
import java.net.*;
public class ImageDemo extends Applet
{
private Image image;
private AppletContext context;
public void init()
{
context = this.getAppletContext();
String imageURL = this.getParameter("image");
if(imageURL == null)
{
imageURL = "java.jpg";
}
try
{
URL url = new URL(this.getDocumentBase(), imageURL);
image = context.getImage(url);
}catch(MalformedURLException e)
{
e.printStackTrace();
// Display in browser status bar
context.showStatus("Could not load image!");
}
}
public void paint(Graphics g)
{
context.showStatus("Displaying image");
g.drawImage(image, 0, 0, 200, 84, null);
g.drawString("www.javalicense.com", 35, 100);
}
}
如下調(diào)用該applet:
<html>
<title>The ImageDemo applet</title>
<hr>
<applet code="ImageDemo.class" width="300" height="200">
<param name="image" value="java.jpg">
</applet>
<hr>
</html>
播放音頻
Applet能通過使用java.applet包中的AudioClip接口播放音頻。AudioClip接口定義了三個方法:
public void play(): 從一開始播放音頻片段一次。
public void loop(): 循環(huán)播放音頻片段
public void stop(): 停止播放音頻片段
為了得到AudioClip對象,你必須調(diào)用Applet類的getAudioClip()方法。無論URL指向的是否是一個真實的音頻文件,該方法都會立即返回結(jié)果。
直到要播放音頻文件時,該文件才會下載下來。
如下實例演示了播放音頻的所有步驟:
import java.applet.*;
import java.awt.*;
import java.net.*;
public class AudioDemo extends Applet
{
private AudioClip clip;
private AppletContext context;
public void init()
{
context = this.getAppletContext();
String audioURL = this.getParameter("audio");
if(audioURL == null)
{
audioURL = "default.au";
}
try
{
URL url = new URL(this.getDocumentBase(), audioURL);
clip = context.getAudioClip(url);
}catch(MalformedURLException e)
{
e.printStackTrace();
context.showStatus("Could not load audio file!");
}
}
public void start()
{
if(clip != null)
{
clip.loop();
}
}
public void stop()
{
if(clip != null)
{
clip.stop();
}
}
}
如下調(diào)用applet:
<html>
<title>The ImageDemo applet</title>
<hr>
<applet code="ImageDemo.class" width="0" height="0">
<param name="audio" value="test.wav">
</applet>
<hr>
你可以使用你電腦上的test.wav來測試上面的實例。
如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!
penJdk1.8中的makefile,記錄下java的執(zhí)行文件編譯過程及jvm編譯過程。
openjdk源碼中有很多目錄,根據(jù)功能做了模塊化劃分,每個目錄實現(xiàn)其相應(yīng)的功能。每個目錄下的結(jié)構(gòu)都差不多,分為src(源碼)、make(makefile)、test(或沒有)、其他特殊目錄。
openjdk
common 一些公共文件,比如下載源碼的shell腳本、生成make的autoconf等文件
corba 分布式通訊接口
hotspot 虛擬機實現(xiàn)
jaxp xml處理代碼
jaxws ws實現(xiàn)
apijdk jdk源碼
langtools java語言工具實現(xiàn),比如javac、javap等
make make文件
nashorn java中js的運行時實現(xiàn)
test 測試文件
src 源碼目錄
bsd bsd實現(xiàn)
linux linux實現(xiàn)
macosx macos實現(xiàn)
share 公用代碼,linux平臺代碼會在這里
solaris solaris實現(xiàn)
windows window實現(xiàn)
make makefile
test 單元測試文件
該目錄主要實現(xiàn)了jdk提供的基于jvm的工具,比如:java, javac, javah, javap等。
langtools
src 源碼目錄
share java源代碼
bin 模板
classes java源碼文件
com 存放了java提供的一些基礎(chǔ)類實現(xiàn),打包成tools.jar
javax
jdk
sample 樣例源碼
make makefile目錄
test 測試用例目錄
可執(zhí)行文件編譯Makefile
文件名為:/openjdk/jdk/make/CompileLaunchers.gmkjava中提供的bin目錄下的java、javac、javap等都不是完全通過c/c++編寫實現(xiàn)的,是通過c/c++入口,啟動虛擬機加載class文件實現(xiàn)的相關(guān)功能。通過c/c++的main函數(shù)入口,創(chuàng)建jvm虛擬機后,通過執(zhí)行相關(guān)功能的java代碼實現(xiàn)其功能,所以java相關(guān)的功能如編譯、運行、查看jvm信息等功能都是通過啟動一個jvm虛擬機或者通過jvmti等實現(xiàn)的。
在makefile文件中可以查看到該部分定義。
ifndef BUILD_HEADLESS_ONLY
$(eval $(call SetupLauncher,appletviewer, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.applet.Main"$(COMMA) }',, \
$(XLIBS)))
endif
$(eval $(call SetupLauncher,extcheck, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.extcheck.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,idlj, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.corba.se.idl.toJavaPortable.Compile"$(COMMA) }'))
$(eval $(call SetupLauncher,jar, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.jar.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,jarsigner, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.security.tools.jarsigner.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,javac, \
-DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javac.Main"$(COMMA) }'))
ifeq ($(ENABLE_SJAVAC), yes)
$(eval $(call SetupLauncher,sjavac, \
-DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.sjavac.Main"$(COMMA) }'))
endif
$(eval $(call SetupLauncher,javadoc, \
-DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javadoc.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,javah, \
-DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javah.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,javap, \
-DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,jdeps, \
-DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.jdeps.Main"$(COMMA) }'))
BUILD_LAUNCHER_jconsole_CFLAGS_windows := -DJAVAW
BUILD_LAUNCHER_jconsole_LDFLAGS_windows := user32.lib
$(eval $(call SetupLauncher,jconsole, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "-J-Djconsole.showOutputViewer"$(COMMA) "sun.tools.jconsole.JConsole"$(COMMA) }' \
-DAPP_CLASSPATH='{ "/lib/jconsole.jar"$(COMMA) "/lib/tools.jar"$(COMMA) "/classes" }'))
$(eval $(call SetupLauncher,jdb, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.example.debug.tty.TTY"$(COMMA) }' \
-DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }'))
$(eval $(call SetupLauncher,jhat, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.hat.Main"$(COMMA) }'))
具體各個具體功能實現(xiàn)可以由makefile中找到相關(guān)的類文件查看實現(xiàn)。這些類在目錄langtools目錄中。
在linux上編譯openjdk的時候,所有java提供的工具程序(bin目錄下的可執(zhí)行程序)入口都是jdk/src/bin/share/bin/main.c。但是具體的功能代碼實現(xiàn)其實是在langtools下通過java代碼實現(xiàn)的,到底是怎么是怎么實現(xiàn)的呢。1、在jdk/src/share/bin/defines.h中通過宏開關(guān)實現(xiàn)了jvm虛擬機執(zhí)行參數(shù)的定義,如下:
#如果定義了JAVA_ARGS宏,則會把jvm的參數(shù)從宏定義中獲取
# 此處參照/openjdk/jdk/make/CompileLaunchers.gmk文件在聲明javac的地方,定義了該宏內(nèi)容
# -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javac.Main"$(COMMA) }')),所以生成的elf文件javac中
# 會得到該值為{ "-J-ms8m"$(COMMA) "com.sun.tools.javac.Main"$(COMMA) }
#ifdef JAVA_ARGS
static const char* const_progname = "java";
static const char* const_jargs[] = JAVA_ARGS;
/*
* ApplicationHome is prepended to each of these entries; the resulting
* strings are concatenated (separated by PATH_SEPARATOR) and used as the
* value of -cp option to the launcher.
*/
#ifndef APP_CLASSPATH
#define APP_CLASSPATH { "/lib/tools.jar", "/classes" }
#endif /* APP_CLASSPATH */
static const char* const_appclasspath[] = APP_CLASSPATH;
#else /* !JAVA_ARGS */
#ifdef PROGNAME
static const char* const_progname = PROGNAME;
#else
static char* const_progname = NULL;
#endif
static const char** const_jargs = NULL;
static const char** const_appclasspath = NULL;
#endif /* JAVA_ARGS */
#ifdef LAUNCHER_NAME
static const char* const_launcher = LAUNCHER_NAME;
#else /* LAUNCHER_NAME */
static char* const_launcher = NULL;
#endif /* LAUNCHER_NAME */
#ifdef EXPAND_CLASSPATH_WILDCARDS
static const jboolean const_cpwildcard = JNI_TRUE;
#else
static const jboolean const_cpwildcard = JNI_FALSE;
#endif /* EXPAND_CLASSPATH_WILDCARDS */
#if defined(NEVER_ACT_AS_SERVER_CLASS_MACHINE)
static const jint const_ergo_class = NEVER_SERVER_CLASS;
#elif defined(ALWAYS_ACT_AS_SERVER_CLASS_MACHINE)
static const jint const_ergo_class = ALWAYS_SERVER_CLASS;
#else
static const jint const_ergo_class = DEFAULT_POLICY;
#endif /* NEVER_ACT_AS_SERVER_CLASS_MACHINE */
最終生成的elf程序常量區(qū)段會有程序名稱及入口的class類名稱。
當(dāng)使用javac編譯java文件時,入口參數(shù)1為java文件路徑,然后啟動一個java虛擬機vm,把com.sun.tools.javac.Main aaa.java傳遞給java虛擬機vm執(zhí)行,傳遞給虛擬機參數(shù)如下:
JavaVM args:
version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 7
option[0] = '-Dsun.java.launcher.diag=true'
option[1] = '-Dapplication.home=/opt/source/jdk8u-dev/build/linux-x86_64-normal-server-slowdebug/jdk'
option[2] = '-Djava.class.path=/opt/source/jdk8u-dev/build/linux-x86_64-normal-server-slowdebug/jdk/lib/tools.jar:/opt/source/jdk8u-dev/build/linux-x86_64-normal-server-slowdebug/jdk/classes'
option[3] = '-Xms8m'
option[4] = '-Dsun.java.command=com.sun.tools.javac.Main aaa.java'
option[5] = '-Dsun.java.launcher=SUN_STANDARD'
option[6] = '-Dsun.java.launcher.pid=5997'
jdk編譯后會生成很多jar包,除了jvm虛擬機提供的一些平臺功能外,其他語言層面的功能都是由java開發(fā)的jar包對外提供的,所以現(xiàn)在有很多語言都基于jvm做了實現(xiàn)。
openjdk提供了由運行時rt.jar, 工具tools.jar,編碼charset.jar等其他功能jar。
下面詳細介紹幾個重要的jar包是怎么生成的。
tools.jar包
tools.jar包在jdk的lib目錄下,主要提供jdk/bin目錄下java工具的虛擬機里面的實現(xiàn)代碼,由java開發(fā)。生成tools.jar包的makefile文件是:文件名為:/openjdk/jdk/make/CreateJars.gmk,內(nèi)容如下:
源碼路徑:langtools目錄
#聲明tools包含的目錄范圍
TOOLS_JAR_INCLUDES := \
com/sun/codemodel \
com/sun/istack/internal/tools \
com/sun/jarsigner \
com/sun/javadoc \
com/sun/jdi \
com/sun/source \
com/sun/tools/attach \
com/sun/tools/classfile \
com/sun/tools/corba \
com/sun/tools/doclets \
com/sun/tools/doclint \
com/sun/tools/example/debug/expr \
com/sun/tools/example/debug/tty \
com/sun/tools/extcheck \
com/sun/tools/hat \
com/sun/tools/internal/jxc \
com/sun/tools/internal/jxc/ap \
com/sun/tools/internal/ws \
com/sun/tools/internal/ws/wscompile/plugin/at_generated \
com/sun/tools/internal/xjc \
com/sun/tools/javac \
com/sun/tools/javadoc \
com/sun/tools/javah \
com/sun/tools/javap \
com/sun/tools/jdeps \
com/sun/tools/jdi \
com/sun/tools/script/shell \
com/sun/xml/internal/dtdparser \
com/sun/xml/internal/rngom \
com/sun/xml/internal/xsom \
org/relaxng/datatype \
sun/applet \
sun/jvmstat \
sun/rmi/rmic \
sun/security/tools/jarsigner \
sun/tools/asm \
sun/tools/attach \
sun/tools/jar \
sun/tools/java \
sun/tools/javac \
sun/tools/jcmd \
sun/tools/jinfo \
sun/tools/jmap \
sun/tools/jps \
sun/tools/jstack \
sun/tools/jstat \
sun/tools/jstatd \
sun/tools/native2ascii \
sun/tools/serialver \
sun/tools/tree \
sun/tools/util
# tools.jar排除sjavac工具
# The sjavac tools is not ready for public consumption.
TOOLS_JAR_EXCLUDES = com/sun/tools/sjavac
#調(diào)用打包生成tools.jar文件
$(eval $(call SetupArchive,BUILD_TOOLS_JAR, , \
SRCS := $(JDK_OUTPUTDIR)/classes, \
SUFFIXES := .class .prp .gif .properties .xml .css .xsd .js .html .txt .java \
Tool aliasmap options, \
INCLUDES := $(TOOLS_JAR_INCLUDES), \
EXCLUDES := $(TOOLS_JAR_EXCLUDES), \
EXTRA_FILES := META-INF/services/com.sun.jdi.connect.Connector \
META-INF/services/com.sun.jdi.connect.spi.TransportService \
META-INF/services/com.sun.tools.attach.spi.AttachProvider \
META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin \
META-INF/services/com.sun.tools.internal.xjc.Plugin, \
JAR := $(IMAGES_OUTPUTDIR)/lib/tools.jar, \
SKIP_METAINF := true, \
CHECK_COMPRESS_JAR := true))
rt.jar包
rt.jar包在jdk的lib目錄下,主要提供java語言層面的運行時庫,由java開發(fā)。rt.jar包含的文件范圍由:/openjdk/jdk/make/profile-rtjar-includes.txt定義,內(nèi)容如下:
#
# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# Included or excluded types must take one of two forms
# - *.class to indicate all classes; or else
# - a full single type name e.g.
# com/sun/security/auth/callback/DialogCallbackHandler$$1.class
# You can not use arbitrary wildcards like DialogCallbackHandler*.class.
#
# Notes:
# - Nested types must use $$ in place of $ as $ is the make meta-character
# - If a package is not listed in any profile's inclusion list then it will
# not appear in any profile. But if a package is also missing from the
# full JRE's inclusion list then it will still be part of the full JRE.
# This is because the full JRE's inclusion lists are only used to define
# the exclusion lists for profiles; they are not used to define the full
# JRE contents - that is still done with the pre-profile legacy mechanism
# (all packagesthat can be found, less those not intended for rt.jar).
# This was done to minimize the impact of profiles on the regular
# non-profile build.
#
PROFILE_1_RTJAR_INCLUDE_PACKAGES := \
com/sun/demo/jvmti/hprof \
com/sun/java/util/jar/pack \
com/sun/net/ssl \
com/sun/nio/file \
com/sun/security/cert/internal/x509 \
java/io \
java/lang \
java/math \
java/net \
java/nio \
java/security \
java/text \
java/time \
java/util \
javax/net \
javax/script \
javax/security \
jdk \
sun/invoke \
sun/launcher \
sun/misc \
sun/net/ \
sun/nio \
sun/reflect \
sun/security \
sun/text \
sun/usagetracker \
sun/util
PROFILE_1_RTJAR_INCLUDE_TYPES :=
PROFILE_1_RTJAR_EXCLUDE_TYPES :=
PROFILE_1_INCLUDE_METAINF_SERVICES :=
PROFILE_2_RTJAR_INCLUDE_PACKAGES := \
com/sun/java_cup/internal/runtime \
com/sun/net/httpserver \
com/sun/org/apache \
com/sun/rmi/rmid \
com/sun/xml/internal/stream \
java/rmi \
java/sql \
javax/rmi/ssl \
javax/sql \
javax/transaction \
javax/xml \
org/w3c \
org/xml/sax \
sun/net/httpserver \
sun/rmi \
sun/util/xml
PROFILE_2_RTJAR_INCLUDE_TYPES :=
PROFILE_2_RTJAR_EXCLUDE_TYPES :=
PROFILE_2_INCLUDE_METAINF_SERVICES := \
META-INF/services/sun.util.spi.XmlPropertiesProvider
PROFILE_3_RTJAR_INCLUDE_PACKAGES := \
com/sun/jmx \
com/sun/jndi \
com/sun/management \
com/sun/naming/internal \
com/sun/nio/sctp \
com/sun/org/apache/xml/internal/security \
com/sun/rowset \
com/sun/security/auth \
com/sun/security/jgss \
com/sun/security/ntlm \
com/sun/security/sasl \
com/sun/tracing \
java/lang/instrument \
java/lang/management \
java/security/acl \
java/util/prefs \
javax/annotation/processing \
javax/lang/model \
javax/management \
javax/naming \
javax/security/auth/kerberos \
javax/security/sasl \
javax/smartcardio \
javax/sql/rowset \
javax/tools \
javax/xml/crypto \
org/ietf/jgss \
org/jcp/xml \
sun/instrument \
sun/management \
sun/net/dns \
sun/net/www/protocol/http/ntlm \
sun/net/www/protocol/http/spnego \
sun/nio/ch/sctp \
sun/security/acl \
sun/security/jgss \
sun/security/krb5 \
sun/security/provider/certpath/ldap \
sun/security/smartcardio \
sun/tracing
PROFILE_3_RTJAR_INCLUDE_TYPES :=
PROFILE_3_RTJAR_EXCLUDE_TYPES := \
com/sun/security/auth/callback/DialogCallbackHandler$$1.class \
com/sun/security/auth/callback/DialogCallbackHandler$$2.class \
com/sun/security/auth/callback/DialogCallbackHandler$$Action.class \
com/sun/security/auth/callback/DialogCallbackHandler$$ConfirmationInfo.class \
com/sun/security/auth/callback/DialogCallbackHandler.class \
javax/management/remote/rmi/_RMIConnectionImpl_Tie.class \
javax/management/remote/rmi/_RMIConnection_Stub.class \
javax/management/remote/rmi/_RMIServerImpl_Tie.class \
javax/management/remote/rmi/_RMIServer_Stub.class
FULL_JRE_RTJAR_INCLUDE_PACKAGES := \
com/oracle \
com/sun/accessibility/internal/resources \
com/sun/activation/registries \
com/sun/awt \
com/sun/beans \
com/sun/corba \
com/sun/image/codec/jpeg \
com/sun/imageio \
com/sun/istack \
com/sun/java/browser \
com/sun/java/swing \
com/sun/jmx/remote/protocol/iiop \
com/sun/jndi/cosnaming \
com/sun/jndi/toolkit/corba \
com/sun/jndi/url/corbaname \
com/sun/jndi/url/iiop \
com/sun/jndi/url/iiopname \
com/sun/media/sound \
com/sun/org/glassfish \
com/sun/org/omg \
com/sun/swing \
com/sun/xml/internal/bind \
com/sun/xml/internal/fastinfoset \
com/sun/xml/internal/messaging \
com/sun/xml/internal/org \
com/sun/xml/internal/stream/buffer \
com/sun/xml/internal/txw2 \
com/sun/xml/internal/ws \
java/applet \
java/awt \
java/beans \
javax/accessibility \
javax/activation \
javax/activity \
javax/imageio \
javax/jws \
javax/print \
javax/rmi/CORBA \
javax/sound \
javax/swing \
javax/xml/bind \
javax/xml/soap \
javax/xml/ws \
org/omg \
sun/applet \
sun/audio \
sun/awt \
sun/corba \
sun/dc \
sun/font \
sun/java2d \
sun/net/ftp \
sun/net/smtp \
sun/net/www/content/audio \
sun/net/www/content/image \
sun/net/www/content/text \
sun/net/www/protocol/ftp \
sun/net/www/protocol/mailto \
sun/net/www/protocol/netdoc \
sun/print \
sun/security/tools/policytool \
sun/swing \
sun/tools/jar
FULL_JRE_RTJAR_INCLUDE_TYPES := \
com/sun/security/auth/callback/DialogCallbackHandler$$1.class \
com/sun/security/auth/callback/DialogCallbackHandler$$2.class \
com/sun/security/auth/callback/DialogCallbackHandler$$Action.class \
com/sun/security/auth/callback/DialogCallbackHandler$$ConfirmationInfo.class \
com/sun/security/auth/callback/DialogCallbackHandler.class \
javax/annotation/*.class \
javax/management/remote/rmi/_RMIConnectionImpl_Tie.class \
javax/management/remote/rmi/_RMIConnection_Stub.class \
javax/management/remote/rmi/_RMIServerImpl_Tie.class \
javax/management/remote/rmi/_RMIServer_Stub.class \
javax/rmi/*.class
FULL_JRE_RTJAR_EXCLUDE_TYPES :=
FULL_JRE_INCLUDE_METAINF_SERVICES := \
META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin \
META-INF/services/com.sun.tools.internal.xjc.Plugin \
META-INF/services/javax.print.PrintServiceLookup \
META-INF/services/javax.print.StreamPrintServiceFactory \
META-INF/services/javax.sound.midi.spi.MidiDeviceProvider \
META-INF/services/javax.sound.midi.spi.MidiFileReader \
META-INF/services/javax.sound.midi.spi.MidiFileWriter \
META-INF/services/javax.sound.midi.spi.SoundbankReader \
META-INF/services/javax.sound.sampled.spi.AudioFileReader \
META-INF/services/javax.sound.sampled.spi.AudioFileWriter \
META-INF/services/javax.sound.sampled.spi.FormatConversionProvider \
META-INF/services/javax.sound.sampled.spi.MixerProvider \
META-INF/services/sun.java2d.cmm.PCMM \
META-INF/services/sun.java2d.pipe.RenderingEngine
生成tools.jar包的makefile文件是:文件名為:/openjdk/jdk/make/CreateJars.gmk,內(nèi)容如下:
#聲明rt排除的范圍
# Full JRE exclude list for rt.jar and resources.jar
# This value should exclude types destined for jars other than rt.jar and resources.jar.
# When building a Profile this value augments the profile specific exclusions
RT_JAR_EXCLUDES += \
com/sun/codemodel \
com/sun/crypto/provider \
com/sun/istack/internal/tools \
com/sun/jarsigner \
com/sun/java/accessibility \
com/sun/javadoc \
com/sun/jdi \
com/sun/net/ssl/internal/ssl \
com/sun/source \
com/sun/tools \
com/sun/xml/internal/dtdparser \
com/sun/xml/internal/rngom \
com/sun/xml/internal/xsom \
javax/crypto \
javax/swing/AbstractButtonBeanInfo.class \
javax/swing/beaninfo \
javax/swing/BoxBeanInfo.class \
javax/swing/JAppletBeanInfo.class \
javax/swing/JButtonBeanInfo.class \
javax/swing/JCheckBoxBeanInfo.class \
javax/swing/JCheckBoxMenuItemBeanInfo.class \
javax/swing/JColorChooserBeanInfo.class \
javax/swing/JComboBoxBeanInfo.class \
javax/swing/JComponentBeanInfo.class \
javax/swing/JDesktopPaneBeanInfo.class \
javax/swing/JDialogBeanInfo.class \
javax/swing/JEditorPaneBeanInfo.class \
javax/swing/JFileChooserBeanInfo.class \
javax/swing/JFormattedTextFieldBeanInfo.class \
javax/swing/JFrameBeanInfo.class \
javax/swing/JInternalFrameBeanInfo.class \
javax/swing/JLabelBeanInfo.class \
javax/swing/JLayeredPaneBeanInfo.class \
javax/swing/JListBeanInfo.class \
javax/swing/JMenuBarBeanInfo.class \
javax/swing/JMenuBeanInfo.class \
javax/swing/JMenuItemBeanInfo.class \
javax/swing/JOptionPaneBeanInfo.class \
javax/swing/JPanelBeanInfo.class \
javax/swing/JPasswordFieldBeanInfo.class \
javax/swing/JPopupMenuBeanInfo.class \
javax/swing/JProgressBarBeanInfo.class \
javax/swing/JRadioButtonBeanInfo.class \
javax/swing/JRadioButtonMenuItemBeanInfo.class \
javax/swing/JScrollBarBeanInfo.class \
javax/swing/JScrollPaneBeanInfo.class \
javax/swing/JSeparatorBeanInfo.class \
javax/swing/JSliderBeanInfo.class \
javax/swing/JSpinnerBeanInfo.class \
javax/swing/JSplitPaneBeanInfo.class \
javax/swing/JTabbedPaneBeanInfo.class \
javax/swing/JTableBeanInfo.class \
javax/swing/JTextAreaBeanInfo.class \
javax/swing/JTextFieldBeanInfo.class \
javax/swing/JTextPaneBeanInfo.class \
javax/swing/JToggleButtonBeanInfo.class \
javax/swing/JToolBarBeanInfo.class \
javax/swing/JTreeBeanInfo.class \
javax/swing/JWindowBeanInfo.class \
javax/swing/SwingBeanInfoBase.class \
javax/swing/text/JTextComponentBeanInfo.class \
META-INF/services/com.sun.jdi.connect.Connector \
META-INF/services/com.sun.jdi.connect.spi.TransportService \
META-INF/services/com.sun.tools.attach.spi.AttachProvider \
META-INF/services/com.sun.tools.xjc.Plugin \
META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor \
org/relaxng/datatype \
sun/awt/HKSCS.class \
sun/awt/motif/X11GB2312.class \
sun/awt/motif/X11GB2312\$$$$Decoder.class \
sun/awt/motif/X11GB2312\$$$$Encoder.class \
sun/awt/motif/X11GBK.class \
sun/awt/motif/X11GBK\$$$$Encoder.class \
sun/awt/motif/X11KSC5601.class \
sun/awt/motif/X11KSC5601\$$$$Decoder.class \
sun/awt/motif/X11KSC5601\$$$$Encoder.class \
sun/jvmstat \
sun/net/spi/nameservice/dns \
sun/nio/cs/ext \
sun/rmi/rmic \
sun/security/ec \
sun/security/internal \
sun/security/mscapi \
sun/security/pkcs11 \
sun/security/provider/Sun.class \
sun/security/rsa/SunRsaSign.class \
sun/security/ssl \
sun/security/tools/jarsigner \
sun/swing/BeanInfoUtils.class \
sun/text/resources/cldr \
sun/tools/asm \
sun/tools/attach \
sun/tools/java \
sun/tools/javac \
sun/tools/jcmd \
sun/tools/jconsole \
sun/tools/jinfo \
sun/tools/jmap \
sun/tools/jps \
sun/tools/jstack \
sun/tools/jstat \
sun/tools/jstatd \
sun/tools/native2ascii \
sun/tools/serialver \
sun/tools/tree \
sun/tools/util \
sun/util/cldr/CLDRLocaleDataMetaInfo.class \
sun/util/resources/cldr \
$(LOCALEDATA_INCLUDES) \
com/oracle/jrockit/jfr \
oracle/jrockit/jfr \
jdk/jfr
# 在jdk編譯輸出classes目錄下查詢所有定義依賴的文件
# Find all files in the classes dir to use as dependencies. This could be more fine granular.
ALL_FILES_IN_CLASSES := $(call not-containing, _the., $(filter-out %javac_state, \
$(call CacheFind, $(JDK_OUTPUTDIR)/classes)))
RT_JAR_MANIFEST_FILE := $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.rt.jar_manifest
RESOURCE_JAR_MANIFEST_FILE := $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.resources.jar_manifest
$(RT_JAR_MANIFEST_FILE): $(MAINMANIFEST) $(BEANMANIFEST)
$(MKDIR) -p $(@D)
$(RM) $@ $@.tmp
$(SED) -e "s#@@RELEASE@@#$(RELEASE)#" \
-e "s#@@COMPANY_NAME@@#$(COMPANY_NAME)#" \
$(MAINMANIFEST) >> $@.tmp
$(ECHO) >> $@.tmp
$(CAT) $(BEANMANIFEST) >> $@.tmp
$(MV) $@.tmp $@
# This defines a target-specific variables to make the shell logic easier to see.
# We need to find the Version.class file for the profile currently being built
$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/rt.jar: \
CLASS_FILE = $(if $(PROFILE), $(strip $(foreach class, $(PROFILE_VERSION_CLASS_TARGETS), $(if $(findstring $(PROFILE), $(class)), $(class)))), NO_SUCH_FILE)
# This is the real target
$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/rt.jar: $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.rt.jar.contents $(RT_JAR_MANIFEST_FILE) $(PROFILE_VERSION_CLASS_TARGETS) $(BEANLESS_CLASSES_TARGETS)
$(ECHO) Creating rt.jar $(PROFILE) Compressed=$(COMPRESS_JARS)
$(MKDIR) -p $(@D)
$(RM) $@ $@.tmp
$(CD) $(JDK_OUTPUTDIR)/classes && \
$(JAR) $(RT_JAR_CREATE_OPTIONS) $@.tmp $(RT_JAR_MANIFEST_FILE) \
@$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.rt.jar.contents && \
if [ -f $(CLASS_FILE) ]; then \
$(ECHO) Updating rt.jar $(PROFILE) && \
$(CD) $(patsubst %$(VERSION_CLASS_PATH), %, $(CLASS_FILE)) && \
$(JAR) $(RT_JAR_UPDATE_OPTIONS) $@.tmp $(VERSION_CLASS_PATH); \
$(CD) $(BEANLESS_CLASSES) && \
$(JAR) $(RT_JAR_UPDATE_OPTIONS) $@.tmp $(CLASSES_TO_DEBEAN); \
fi
$(MV) $@.tmp $@
jconsole.jar
jconsole.jar包在jdk的lib目錄下,是一個Java監(jiān)視和管理控制臺的客戶端程序,由javax swing開發(fā)。jsoncole可以附加本地java進程,通過api查詢方式或者使用jms協(xié)議查詢java虛擬機一些觀測數(shù)據(jù)。jconsole.jar主要組成由jdk/src/share/classes/sun/tools/jconsole、jdk/src/share/classes/com/sun/tools/jconsole目錄下文件組成。
jdk本身提供了2中方式,一種是bin目錄下的jconsole程序,另外一種就是lib下的jconsole.jar包。bin下的jsoncole直接運行,啟動打開jconsole的main入口, lib下的jsoncole.jar需要使用java -jar jsoncole.jar運行。
向?qū)ο蠛兔嫦蜻^程的區(qū)別
面向過程:
優(yōu)點:性能比面向?qū)ο蟾撸驗轭愓{(diào)用時需要實例化,開銷比較大,比較消耗資源;比如單片機、嵌入式開發(fā)、Linux/Unix等一般采用面向過程開發(fā),性能是最重要的因素。
缺點:沒有面向?qū)ο笠拙S護、易復(fù)用、易擴展。
面向?qū)ο螅?/p>
優(yōu)點:易維護、易復(fù)用、易擴展,由于面向?qū)ο笥蟹庋b、繼承、多態(tài)性的特性,可以設(shè)計出低耦合的系統(tǒng),使系統(tǒng)更加靈活、更加易于維護。
缺點:性能比面向過程低
Java語言有哪些特點?
1,簡單易學(xué);2,面向?qū)ο螅ǚ庋b,繼承,多態(tài));3,平臺無關(guān)性(Java虛擬機實現(xiàn)平臺無關(guān)性);4,可靠性;5,安全性;6,支持多線程(C++語言沒有內(nèi)置的多線程機制,因此必須調(diào)用操作系統(tǒng)的多線程功能來進行多線程程序設(shè)計,而Java語言卻提供了多線程支持);7,支持網(wǎng)絡(luò)編程并且很方便(Java語言誕生本身就是為簡化網(wǎng)絡(luò)編程設(shè)計的,因此Java語言不僅支持網(wǎng)絡(luò)編程而且很方便);8,編譯與解釋并存;
什么是字節(jié)碼?采用字節(jié)碼的最大好處是什么?什么Java是虛擬機?
先看下java中的編譯器和解釋器:Java中引入了虛擬機的概念,即在機器和編譯程序之間加入了一層抽象的虛擬的機器。這臺虛擬的機器在任何平臺上都提供給編譯程序一個的共同的接口。編譯程序只需要面向虛擬機,生成虛擬機能夠理解的代碼,然后由解釋器來將虛擬機代碼轉(zhuǎn)換為特定系統(tǒng)的機器碼執(zhí)行。在Java中,這種供虛擬機理解的代碼叫做字節(jié)碼(即擴展名為.class的文件),它不面向任何特定的處理器,只面向虛擬機。每一種平臺的解釋器是不同的,但是實現(xiàn)的虛擬機是相同的。Java源程序經(jīng)過編譯器編譯后變成字節(jié)碼,字節(jié)碼由虛擬機解釋執(zhí)行,虛擬機將每一條要執(zhí)行的字節(jié)碼送給解釋器,解釋器將其翻譯成特定機器上的機器碼,然后在特定的機器上運行,這就是上面提到的Java的特點的編譯與解釋并存的解釋。Java源代碼---->編譯器---->jvm可執(zhí)行的Java字節(jié)碼(即虛擬指令)---->jvm---->jvm中解釋器----->機器可執(zhí)行的二進制機器碼---->程序運行。采用字節(jié)碼的好處: Java語言通過字節(jié)碼的方式,在一定程度上解決了傳統(tǒng)解釋型語言執(zhí)行效率低的問題,同時又保留了解釋型語言可移植的特點。所以Java程序運行時比較高效,而且,由于字節(jié)碼并不專對一種特定的機器,因此,Java程序無須重新編譯便可在多種不同的計算機上運行。
什么是Java虛擬機
?任何一種可以運行Java字節(jié)碼的軟件均可看成是Java的虛擬機(JVM)
什么是Java程序的主類?應(yīng)用程序和小程序的主類有何不同?
一個程序中可以有多個類,但只能有一個類是主類。在Java應(yīng)用程序中,這個主類是指包含main()方法的類。而在Java小程序中,這個主類是一個繼承自系統(tǒng)類JApplet或Applet的子類。應(yīng)用程序的主類不一定要求是public類,但小程序的主類要求必須是public類。主類是Java程序執(zhí)行的入口點。
什么是JDK?什么是JRE?
JDK: 顧名思義它是給開發(fā)者提供的開發(fā)工具箱,是給程序開發(fā)者用的。它除了包括完整的JRE(Java Runtime Environment),Java運行環(huán)境,還包含了其他供開發(fā)者使用的工具包。
JRE:普通用戶而只需要安裝JRE(Java Runtime Environment)來 來運行Java程序。而程序開發(fā)者必須安裝JDK來編譯、調(diào)試程序。
環(huán)境變量Path和ClassPath的作用是什么?如何設(shè)置這兩個環(huán)境變量?
Java環(huán)境變量PATH和CLASSPATH
Java應(yīng)用程序與小程序之間有那些差別?
簡單說應(yīng)用程序是從主線程啟動(也就是main()方法)。applet小程序沒有main方法,主要是嵌在瀏覽器頁面上運行(調(diào)用init()線程或者run()來啟動),嵌入瀏覽器這點跟flash的小游戲類似。
字符型常量和字符串常量的區(qū)別
Java語言采用何種編碼方案?有何特點?
Java語言采用Unicode編碼標(biāo)準(zhǔn),Unicode(標(biāo)準(zhǔn)碼),它為每個字符制訂了一個唯一的數(shù)值,因此在任何的語言,平臺,程序都可以放心的使用。
構(gòu)造器Constructor是否可被override
在講繼承的時候我們就知道父類的私有屬性和構(gòu)造方法并不能被繼承,所以Constructor也就不能被override,但是可以overload,所以你可以看到一個類中有多個構(gòu)造函數(shù)的情況。
重載和重寫的區(qū)別
重載:發(fā)生在同一個類中,方法名必須相同,參數(shù)類型不同、個數(shù)不同、順序不同,方法返回值和訪問修飾符可以不同,發(fā)生在編譯時。
重寫:發(fā)生在父子類中,方法名、參數(shù)列表必須相同,返回值小于等于父類,拋出的異常小于等于父類,訪問修飾符大于等于父類;如果父類方法訪問修飾符為private則子類中就不是重寫。
java 面向?qū)ο笕筇匦裕ǚ庋b,繼承,多態(tài))以及抽象、接口的介紹,訪問控制符public,protected,private,以及默認(rèn)的區(qū)別
https://www.2cto.com/kf/201605/509637.html
String和StringBuffer、StringBuilder的區(qū)別是什么?String為什么是不可變的?
可變性:String類中使用字符數(shù)組保存字符串,private?final?char?value[],所以string對象是不可變的。StringBuilder與StringBuffer都繼承自AbstractStringBuilder類,在AbstractStringBuilder中也是使用字符數(shù)組保存字符串,char[]value,這兩種對象都是可變的。
線程安全性:String中的對象是不可變的,也就可以理解為常量,線程安全。AbstractStringBuilder是StringBuilder與StringBuffer的公共父類,定義了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer對方法加了同步鎖或者對調(diào)用的方法加了同步鎖,所以是線程安全的。StringBuilder并沒有對方法進行加同步鎖,所以是非線程安全的。
性能:每次對String 類型進行改變的時候,都會生成一個新的String對象,然后將指針指向新的String 對象。StringBuffer每次都會對StringBuffer對象本身進行操作,而不是生成新的對象并改變對象引用。相同情況下使用StirngBuilder 相比使用StringBuffer 僅能獲得10%~15% 左右的性能提升,但卻要冒多線程不安全的風(fēng)險。
對于三者使用的總結(jié):如果要操作少量的數(shù)據(jù)用 = String單線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuilder多線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuffer
自動裝箱與拆箱
裝箱:將基本類型用它們對應(yīng)的引用類型包裝起來;
拆箱:將包裝類型轉(zhuǎn)換為基本數(shù)據(jù)類型;
Java使用自動裝箱和拆箱機制,節(jié)省了常用數(shù)值的內(nèi)存開銷和創(chuàng)建對象的開銷,提高了效率,由編譯器來完成,編譯器會在編譯期根據(jù)語法決定是否進行裝箱和拆箱動作。
類、方法、成員變量和局部變量的可用修飾符 -
http://blog.csdn.net/yttcjj/article/details/6939239
在一個靜態(tài)方法內(nèi)調(diào)用一個非靜態(tài)成員為什么是非法的?
由于靜態(tài)方法可以不通過對象進行調(diào)用,因此在靜態(tài)方法里,不能調(diào)用其他非靜態(tài)變量,也不可以訪問非靜態(tài)變量成員。
在Java中定義一個不做事且沒有參數(shù)的構(gòu)造方法的作用
Java程序在執(zhí)行子類的構(gòu)造方法之前,如果沒有用super()來調(diào)用父類特定的構(gòu)造方法,則會調(diào)用父類中“沒有參數(shù)的構(gòu)造方法”。因此,如果父類中只定義了有參數(shù)的構(gòu)造方法,而在子類的構(gòu)造方法中又沒有用super()來調(diào)用父類中特定的構(gòu)造方法,則編譯時將發(fā)生錯誤,因為Java程序在父類中找不到?jīng)]有參數(shù)的構(gòu)造方法可供執(zhí)行。解決辦法是在父類里加上一個不做事且沒有參數(shù)的構(gòu)造方法。
接口和抽象類的區(qū)別是什么?
1.接口的方法默認(rèn)是public,所有方法在接口中不能有實現(xiàn),抽象類可以有非抽象的方法2.接口中的實例變量默認(rèn)是final類型的,而抽象類中則不一定3.一個類可以實現(xiàn)多個接口,但最多只能實現(xiàn)一個抽象類4.一個類實現(xiàn)接口的話要實現(xiàn)接口的所有方法,而抽象類不一定5.接口不能用new實例化,但可以聲明,但是必須引用一個實現(xiàn)該接口的對象從設(shè)計層面來說,抽象是對類的抽象,是一種模板設(shè)計,接口是行為的抽象,是一種行為的規(guī)范。
成員變量與局部變量的區(qū)別有那些?
創(chuàng)建一個對象用什么運算符?對象實體與對象引用有何不同?
new運算符,new創(chuàng)建對象實例(對象實例在堆內(nèi)存中),對象引用指向?qū)ο髮嵗▽ο笠么娣旁跅?nèi)存中)。一個對象引用可以指向0個或1個對象(一根繩子可以不系氣球,也可以系一個氣球);一個對象可以有n個引用指向它(可以用n條繩子系住一個氣球)
什么是方法的返回值?返回值在類的方法里的作用是什么?
方法的返回值是指我們獲取到的某個方法體中的代碼執(zhí)行后產(chǎn)生的結(jié)果!(前提是該方法可能產(chǎn)生結(jié)果)。返回值的作用:接收出結(jié)果,使得它可以用于其他的操作!
一個類的構(gòu)造方法的作用是什么?若一個類沒有聲明構(gòu)造方法,改程序能正確執(zhí)行嗎?為什么?
主要作用是完成對類對象的初始化工作。可以執(zhí)行。因為一個類即使沒有聲明構(gòu)造方法也會有默認(rèn)的不帶參數(shù)的構(gòu)造方法。
構(gòu)造方法有哪些特性?
1,名字與類名相同;2,沒有返回值,但不能用void聲明構(gòu)造函數(shù);3,生成類的對象時自動執(zhí)行,無需調(diào)用。
靜態(tài)方法和實例方法有何不同?
靜態(tài)方法和實例方法的區(qū)別主要體現(xiàn)在兩個方面:
對象的相等與指向他們的引用相等,兩者有什么不同?
對象的相等 比的是內(nèi)存中存放的內(nèi)容是否相等而 引用相等 比較的是他們指向的內(nèi)存地址是否相等。
在調(diào)用子類構(gòu)造方法之前會先調(diào)用父類沒有參數(shù)的構(gòu)造方法,其目的是?
幫助子類做初始化工作。
什么是多態(tài)機制?Java語言是如何實現(xiàn)多態(tài)的?
多態(tài)
equals 和 == 的區(qū)別?
通俗點講:==是看看左右是不是一個東西。equals是看看左右是不是長得一樣。如何記住嘛。如果單純是想記住,==:等于。equals:相同。兩個長得一樣的人,只能說長的相同(equals),但是不等于他們倆是一個人。你只要記住equals,==就不用記了。你們?nèi)ジ惺芤幌隆?/p>
術(shù)語來講的區(qū)別:1.==是判斷兩個變量或?qū)嵗遣皇侵赶蛲粋€內(nèi)存空間 equals是判斷兩個變量或?qū)嵗赶虻膬?nèi)存空間的值是不是相同 2.==是指對內(nèi)存地址進行比較 equals()是對字符串的內(nèi)容進行比較3.==指引用是否相同 equals()指的是值是否相同
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。