Java Basics
Introduction
Java Basics.
Table of Contents
- Introduction
- Table of Contents
- Functional
- Http Client
- Dropwizard
- Data Types
- Collections
- 系统属性
- File 类
- Comparison
- Input/Output
- 图形界面应用程序
- 通过鼠标双击直接运行java程序
Functional
@FunctionalInterface
public interface Provider<T> {
T get() throws Exception;
}
@FunctionalInterface
public interface Fn<T, R> {
R apply(T input) throws Exception;
default <V> Fn<V, R> compose(Fn<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Fn<T, V> andThen(Fn<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
}
Throwable Return Value Wrap
@Accessors(fluent = true)
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class Try<T> {
@Getter
private final T value;
@Getter
private final Exception exception;
public static <T> Try<T> success(final T v) {
return new Try<>(v, null);
}
public static <T> Try<T> failure(final Exception e) {
return new Try<>(null, e);
}
public static <T> Try<T> of(Provider<T> provider) {
try {
return success(provider.get());
} catch (Exception e) {
return failure(e);
}
}
public void succeeded(Consumer<? super T> consumer) {
if (value != null) consumer.accept(value);
}
public <R> Try<R> map(Fn<? super T, ? extends R> mapper) {
Objects.requireNonNull(mapper);
try {
if (value != null) return success(mapper.apply(value));
else throw exception;
} catch (Exception e) {
return failure(e);
}
}
public <U> Try<U> flatMap(Function<? super T, Try<U>> mapper) {
Objects.requireNonNull(mapper);
if (succeeded())
return mapper.apply(value);
else {
return failure(exception);
}
}
public <R> R unify(BiFunction<T, Exception, R> fn) {
return fn.apply(value, exception);
}
public <R> R exceptionally(Function<Exception, R> fn) {
if (exception != null) return fn.apply(exception);
return null;
}
public boolean succeeded() {
return exception == null;
}
@Override
public int hashCode() {
return succeeded() ? value.hashCode() : exception.hashCode();
}
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other instanceof Try) {
Try o = (Try) other;
return Objects.equals(value, o.value) && Objects.equals(exception, o.exception);
}
return false;
}
@Override
public String toString() {
return succeeded() ? String.format("Try.success[%s]", value) : String.format("Try.failure[%s]", exception);
}
}
Http Client
TrustPinnedSelfSignedStrategy
public class TrustPinnedSelfSignedStrategy extends TrustSelfSignedStrategy {
private final String host;
private final X509Certificate certificate;
public TrustPinnedSelfSignedStrategy(String host, X509Certificate certificate) {
this.host = host;
this.certificate = certificate;
}
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
System.out.println("validating");
System.out.println(chain);
System.out.println(authType);
boolean ret = super.isTrusted(chain, authType) && chain[0].equals(certificate);
System.out.println(chain[0]);
System.out.println(certificate);
return ret;
}
}
Dropwizard
public class DireApplication extends Application<DireConfiguration> {
private static final Injector injector = Guice.createInjector(new DireModule());
public static void main(String[] args) throws Exception {
injector.getInstance(DireApplication.class).run(args);
}
@Override
public void initialize(Bootstrap<DireConfiguration> bootstrap) {
bootstrap.setConfigurationSourceProvider(
new SubstitutingSourceProvider(
bootstrap.getConfigurationSourceProvider(),
new EnvironmentVariableSubstitutor(false)
)
);
}
@Override
public void run(DireConfiguration configuration, Environment environment) {
environment.jersey().register(injector.getInstance(DireResource.class));
}
}
Data Types
- bool, byte, char, short, int, float, long, double
- Boolean, Byte, Char, Short, Integer, Float, Long, Double
Collections
-
集合,无序和互异,如果add两个一样的值,只有一个。
- HashSet
- TreeSet
import java.util.*; Set s=new HashSet(); s.add("One");
-
列表:java为列表定义了一个接口List,常用的有ArrayList、Vector等。
- LinkedList
- ArrayList
- Vector (thread-safe)
import java.util.*; List s=new ArrayList(); //数组 s.add("aaa"); // 添加元素 s.remove(2); //删除,索引号从0开始。
-
Iterator接口:集合和列表都有个iterator()方法 ,可以列出各个元素。
import java.util.*; public class Test { public static void main(String[] args) { List<String> s = new ArrayList<String>(); s.add("aaa"); s.add("ccc"); s.add("bbb"); Iterator it = s.iterator(); //iterator()返回类型为Iterator。 while (it.hasNext()) { System.out.println(it.next()); //用next()方法遍历元素。 } } }
-
映射Map
Map也是一个接口,常用类是HashMap,通过put()方法将两个对象放进去。通过get()方法将映射关系取出。
- HashMap
- ConcurrentHashMap
- HashTable (thread-safe)
- LinkedHashMap
- TreeMap
import java.util.*; public class Test { public static void main(String[] args) { Map<String, String> m = new HashMap<String, String>(); m.put("name", "oxnz"); m.put("loc", "Wuhan"); Object o = m.get("name"); //所有的类都是Object的子类。 System.out.println("name: " + o + "nLocation: " + m.get("loc")); } }
-
排序:最简单的方法使用Arrays类的静态方法sort。可以对各种数组进行排序。
- Arrays.sort()
- Collection.sort()
int[] a = {2, 9, 2, 4, 5, 8}; Arrays.sort(a);
系统属性
1、System类的静态方法getProperty(属性名称)可以获得用户计算机的各种属性。
如:user.dir
代表当前程序运行的目录,file.separator
代表文件分隔符,不同系统中文件分隔符不同。有的是"/"
,有的是""
。
System.out.println(System.getProperty("user.dir") + System.getProperty("file.separator"));
// 输出(OS X 系统):/Users/oxnz/Developer/tmp/
2、若要获取当前系统中有哪些属性,可以使用System类的静态方法getProperties(),它将返回一个Properties类型的对象,其中包含的是属性名称与属性值的映射关系。
import java.util.*;
public class Test {
public static void main(String[] args) {
Properties pps = System.getProperties();
Enumeration e = pps.propertyNames();
while (e.hasMoreElements()) {
String pname = (String)e.nextElement();
System.out.println(pname + ": " + System.getProperty(pname));
}
}
}
// 输出:
...
user.name: oxnz
java.class.path: .
java.vm.specification.version: 1.8
sun.arch.data.model: 64
java.home: /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre
sun.java.command: Test
java.specification.vendor: Oracle Corporation
user.language: zh
awt.toolkit: sun.lwawt.macosx.LWCToolkit
java.vm.info: mixed mode
java.version: 1.8.0
...
File 类
File类可以代表文件或目录,如:
File d = new File("/home/oxnz/");
File f = new File("/home/oxnz/.bashrc");
1、获得当前路径,并在当前路径建立文件。
String prefix = System.getProperty("user.dir") + System.getProperty("file.separator");
File f = new File(prefix + "test.txt");
2、File类提供的方法:
delete()
删除mkdir()
创建File所代表的目录rename(File newName)
更改名称isFile()
判断是否为文件isDirectory()
判断是否为目录lastModified()
显示该文件上次修改时间,毫秒。length()
返回文件长度list()
返回字符串类型数组,数组元素是File对象所代表的目录下所有的目录和文件的名称。
import java.io.*;
File path = new File("/path/to/tmp");
path.mkdir();
3、遍历输出指定目录的文件。
import java.util.*;
import java.io.*;
public class Test {
public static void main(String[] args) {
tree(".");
}
public static void tree(String fpath) {
tree(fpath, "");
}
public static void tree(String fpath, String prefix) {
File f = new File(fpath);
System.out.println(prefix + fpath);
if (f.isDirectory()) {
if (prefix.equals("")) {
prefix = "|_______";
} else { // if (prefix.equals("|_______")) {
prefix = " " + prefix;
}
for (String fp : f.list()) {
tree(fp, prefix);
}
}
}
}
// 运行效果类似 Linux 的 tree 命令:
% java Test
.
|_______.DS_Store
|_______a
|_______b
|_______Makefile
|_______test
|_______Test.class
|_______test.cpp
|_______Test.java
Comparison
- 简单类型
- java中的比较操作有两种:使用
==
运算符和使用equals()
方法。简单类型不是对象,因而只能用==
而不能用equals()
进行比较。
- java中的比较操作有两种:使用
- 参考类型
- 特殊类型
Input/Output
- 键盘输入和屏幕输出
read()
, write()
方法的使用参见API文档,一般常用 read(char[] buf, int offset, int length)
, 表示读取length
长度的字符存入cbuf
的第offset
个单元中。
write
对应相反。
byte buffer[] = new byte[255];
System.in.read(buffer,0,255);
String s = new String(buffer);
System.out.println(s);
read()
方法按字符读取,结束时将返回-1,因此如果要多次从输入流中读取数据,可以将其作为循环条件。
2、处理流:处理输入流
System.in
中的read()
不带参数时只能一次读取一个字符,或者像1、当中使用,如果想要一次读入一行,则可以将其作为参数传递给其他输入流,这些流称为处理流或过滤流,可以提供其他方式来处理输入输出流。
如:类BufferedReader
提供了readLine()
方法可以一次从流中读取一行,其构造参数为Reader
类型。而类InputStreamReader
是Reader
的子类,构造器参数为输入流System.in
。因此可以如下构造处理流:
InputStreamReader ir = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(ir);
while(in.readLine()!=null){
// ...
}
以上可简写为:
in=new BufferedReader(new InputStreamReader(System.in));
3、基本文件输入输出
java中提供了FileInputStream
和FileOutputStream
来处理文件输入/输出操作,参数可以是字符串代表的文件,也可以是File
类型的对象。这两个类分别提供了read()
和write()
方法来读写文件。结束返回-1 。
FileInputStream fileIn=new FileInputStream(“c:test.txt”);
int b;
while((b=fileIn.read())!=-1) {
System.out.print((char)b);
}
也可以用处理流一次读取一行,如下:
BufferedReader in = new BufferedReader (new InputStreamReader (new FileInputStream ("c:test.txt")));
while(in.readLine()!=null) {
}
read()
和write()
:
byte buffer[]=new byte[80];
int bytes=System.in.read(buffer); //返回值为实际读入的字符数
FileOutputStream fileOut=new FileOutputStream(“line.txt”);
fileOut.write(buffer,0,bytes); //将buffer内容输出到文件。
同样,写也可以制造处理流一次写入一行:
BufferedWriter out=new BufferedWriter(new InputStreamWriter(new FileOutputStream("line.txt")));
4、字节流和字符流
字节流按照字节(8位)传输;字符流按照字符(16位)传输。由于字符使用Unicode字符集,支持多国文字,因此若流要跨越多种平台,应使用字符流。
1)常用的字节型的节点流有:(8位)
文件:FileInputStream
, FileOutputStream
内存(数组):ByteArrayInputStream
, ByteArrayOutputStream
管道:PipedInputStream
, PipedOutputStream
2)常用的字符型的节点流有:(16位)
文件:FileReader
, FileWriter
内存(数组):CharArrayReader
,CharArrayWriter
管道:PipedReader
, PipedWriter
同样,处理流也有面向字符和面向字节之分,成用的有:
1)面向字节的处理流 (8位)
BufferedInputStream
, BufferedOutputStream
,DataInputStream
, DataOutputStream
2)面向字符的处理流 (16位)
BufferedWriter
, BufferedReader
,InputStreamReader
, InputStreamWriter
可见,字节类型的叫Stream
,字符类型的叫Reader/Writer
。InputStreamReader/Writer
用于将字节流按照指定的字符集转换成字符流。
对于文件有两种操作,FileInputStream
和FileReader/Writer
,前者为8位,后者16位。BufferedReader/Writer
的参数为Reader
类,即为16位的。对于文件处理流可以如下:
BufferedReader in=new BufferedReader(new FileReader("test.txt"));
5、文件随机读写
使用RandomAccessFile
类可以实现文件的随机读写,即从文件的任意一个位置开始读写。一般的流中,文件指针只能顺序移动,而RandomAccessFile
可以任意移动指针。
RandomAccessFile raf = new RandomAccessFile
(文件名,模式);文件名和模式都是字符串类型,模式"r"
代表以只读方式访问文件,"rw"
代表既可以读文件又可以写文件。
seek(long pos)
方法将文件指针移动到文件开头pos个字节处。
getFilePointer()
返回当前的文件指针的位置。
length()
返回文件长度。
例:向文件的末尾添加一个字符串“hi”
import java.io.*;
public class Test {
public static void main(String[] args) {
RandomAccessFile f;
try {
f = new RandomAccessFile("test.txt", "rw");
f.seek(f.length());
f.writeUTF("hin");
} catch (Exception e) {
System.out.println("error");
}
}
}
RandomAccessFile
提供了一系列的方法对文件进行各种类型的读写。如writeChar(),writeInt(),readChar(),readInt()
等。
6、自己编写处理流
定义处理流只要定义FilterInputStream
类的子类,在处理流的构造器中传入需要处理的流,然后定义一些方法利用传入的流进行所需的处理即可。
列:构造处理流,对于输入的字符,只输出数字和回车符,其他字符按空格输出。
class NZInputStream extends FilterInputStream {
public NZInputStream(InputStream in) {
super(in);
}
public int read() throws IOException {
int c = in.read();
if (-1 == c) { //结束则返回-1
return c;
} else if (Character.isDigit((char)c) || (char)c == 'n') {
return c; //数字或回车也返回
} else {
return ' '; //其他字符返回空格。
}
}
}
7、对象流
8、通过URL对象访问网页
import java.util.*;
import java.net.*;
import java.io.*;
public class Test {
public static void main(String[] args) {
URL url;
try {
url = new URL("http://oxnz.github.io");
InputStream in = url.openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String s = reader.readLine();
while (null != s) {
System.out.println(s);
s = reader.readLine();
}
} catch (Exception e) {
System.out.println("error");
}
}
}
// 输出:
<!DOCTYPE html>
<!--[if IE 7]>
<html class="ie ie7" lang="en-US">
<![endif]-->
<!--[if IE 8]>
<html class="ie ie8" lang="en-US">
<![endif]-->
<!--[if !(IE 7) | !(IE 8) ]><!-->
<html lang="en-US">
<!--<![endif]-->
<head>
<meta charset="UTF-8">
...
输入输出流小结:
read()
方法:按字符读取,-1表示结束。
read(buffer)
:读入数据存入buffer
。
read(buffer, offset, length)
: 读入数据存入buffer
的offset
位置
若要读取行,则必须应用处理流。
图形界面应用程序
java中各种图形组件如按钮对话框都是Component
类的子类,放在容器(Container
)中。java中的容器有两类:窗口Window
和面板Panel
。窗口是可以独立存在的容器,Panel
必须放在其他容器中,如窗口或浏览器窗口中。
窗口有两类,一类是具有标题栏、最大化、最小化、按钮的Frame
,另一类是对话框Dialog
。
使用Frame
的主要步骤是:
import java.awt.*;
public class Test {
public static void main(String[] args) {
Frame f = new Frame("NZ");
f.setSize(400, 600);
f.pack(); //自动调整窗口大小
f.setVisible(true);
f.setBackground(Color.blue); //设置背景颜色
}
}
常用图形组件
按钮 Button
Panel p = new Panel();
Button b = new Button("NZTest");
p.add(b);
f.add(p);
复选框 Checkbox
Checkbox c = new Checkbox("test",true);
// 第二个参数表示默认选中,否则为 false
单选项 Radio
CheckboxGroup g = new CheckboxGroup();
Checkbox c = new Checkbox("Test", g, true); //添加了一个组分类g
下拉列表框
Choice c = new Choice();
c.addItem("choice 1");
列表框 跟下拉列表框类似,只是可以一次显示多行,自动生成滚动条。
List l = new List(4,true); // 4表示行数,true表示支持多选。
l.add("listx"); //添加超过四个时,自动生成滚动条。
对话框
对话框和Frame都是窗口类型,对话框和Frame相关联,但不是放在Frame中。
Frame f = new Frame("NZFrame");
Dialog d = new Dialog(f, "Test" ,true);
第一个参数为与之相关联的Frame
,第三个参数表示对话框处理完毕才可以和Frame
交互。就像Word软件,选择“文件/打开”之后出现的对话框。
文件对话框
文件对话框显示一个对话框让用户选择文件,该对话框用于点击打开文件时调用。语法结构为:
FileDialog d = new FileDialog(f, "Selectable");
用户选择了哪个文件可由对话框方法getDirectory()
和getFile()
获得。返回为字符串。
如:String s = d.getDirectory() + d.getFile();
标签
Label l = new Label("Label");
滚动面板
对于较大的图形界面,可以放在滚动面板中,然后将滚动面板放在Frame
中。
Frame f = new Frame("NZFrame");
ScrollPane sp = new ScrollPane();
Panel p = new Panel();
f.add(sp);
sp.add(p);
单行文本框
TextField tf = new TextField(String s,int length);
多行文本输入框
TextArea ta = new TextArea(String s,int row,int width);
菜单
在Frame中设置菜单栏-》菜单栏中添加菜单-》菜单中添加菜单项。
Frame f = new Frame("NZFrame");
MenuBar mb = new MenuBar();
Menu m1 = new Menu("File");
MenuItem m11 = new MenuItem("Open");
MenuItem m12 = new MenuItem("Save");
m1.add(m11);
m1.add(m12);
mb.add(m1);
f.setMenuBar(mb);
分隔符:m1.addSeparator();
菜单选中:如自动换行。使用CheckBoxMenuItem
.
快捷菜单(常用于右键单击)
对于不需要放在固定位置的快捷菜单,可以使用PopupMenu
来实现,和普通菜单Menu
的使用方法一样,可以添加各种菜单项、选择项、分隔符等。使用show()
方法可以指定快捷菜单的显示位置。通常读取鼠标右击的位置来确定快捷菜单在何处显示。
Frame f=new Frame("MENU");
PopupMenu m1=new PopupMenu("File");
MenuItem m11=new MenuItem("Open");
MenuItem m12=new MenuItem("Save");
m1.add(m11);
m1.add(m12);
f.add(m1);
m1.show(f,20,50); // 第一个参数是各种组件,后面两个参数是快捷菜单相对于第一个组件的相对显示位置。
布局
流布局
流布局从左到右,自上而下的顺序放置组件。其使用方式是:
其语法结构为:
FlowLayout layout = new FlowLayout();
或FlowLayout layout = new FlowLayout(FlowLayout.RIGHT);
或FlowLayout layout = new FlowLayout(FlowLayout.LEFT,10,20);
后边两个参数表示组件左右、上下间隔多少像素。
使用:f.setLayout(t);
或者f.setLayout(new FlowLayout());
边界布局
网格布局
卡片布局
网格包布局
绘图操作
Java中使用Graphics
对象可以进行各种绘图操作。定义Panel
的子类,重写paint()
方法。在该方法的参数中只有一个Graphics
对象。窗口刷新时自动执行paint()
方法。
import java.awt.*;
public class Test extends Panel {
public static void main(String[] args) {
Frame f = new Frame("NZ");
Test t = new Test();
f.add("Center", t);
f.setSize(400, 600);
f.setVisible(true);
}
public void paint(Graphics g) {
System.out.println("repaint");
Font f = new Font("TimesRoman", Font.BOLD, 18);
g.setFont(f); //设置字体
g.drawString("Hello world!", 10, 60);
g.drawOval(50, 50, 30, 30); //画椭圆
g.fillRect(200, 200, 40, 80);
}
}
事件处理
用户单击按钮,自动产生的对象为ActionEvent
,自动执行ActionPerformed()
方法;按动键盘,自动产生的对象为KeyEvent
,自动执行KeyPressed()
,KeyReleased()
,KeyTyped()
方法。
按钮事件处理
对于鼠标单击按钮的事件,编写事件处理器时需要实现的接口为:ActionListener
,该接口中只有一个方法需要实现:ActionPerformed(ActionEvent e)
。程序可以如下:
import java.awt.event.*;
class Test implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand()); //可以获得用户单击的按钮所对应的字符串。
}
}
按钮添加监听:button.addActionListener(事件处理器);
键盘处理事件
import java.awt.*;
import java.awt.event.*;
public class Test implements KeyListener{ //接口
public void keyTyped(KeyEvent ev) { //接口方法
char c=ev.getKeyChar();
System.out.println(“keyTyped”+c);
}
public void keyPressed(KeyEvent ev) {
...
}
public void keyRealeased(KeyEvent ev){
...
}
}
鼠标事件的处理
实现的接口有两类:一类是MouseListener
,它处理鼠标单击以及鼠标进出操作;另一类是MouseMotionListener
,它处理鼠标拖动和移动操作。使用时可以实现其中的一个接口,也可以两个都实现。
对于MouseMotionListener
,拖动鼠标将执行mouseDragged()
,移动鼠标将执行mouseMoved()
。
对于MouseListener
,鼠标按钮按下将执行mousePressed()
,鼠标按钮释放将执行mouseReleased()
,鼠标按钮单击将执行mouseClicked()
,鼠标进入组件所在区域将执行mouseEntered()
,鼠标离开组件将执行mouseExited()
。
方法的参数为MouseEvent
,通过其getX()
和getY()
方法可以获得鼠标的位置,getClickCount()
方法可获得单击次数,通过paramString()
方法可以获得各种参数,包括单击的模式,由此可判断鼠标操作使用的是左按钮还是右按钮或中间按钮。
import java.awt.*;
import java.awt.event.*;
public class Test implemets MouseListener,MouseMotionListener{
// 对某一组件添加监听。
public void mouseMoved(MouseEvent ev){
int x=ev.getX();
int y=ev.getY();
System.out.println(“mouseMoved”+x+y);
}
...其它方法类似
}
窗口事件处理
接口:WindowListener
。
方法:打开执行windowOpened()
,单击窗口右上角关闭按钮执行windowClosing()
,单击最小化按钮执行windowIconified()
和windowDeactivated()
,鼠标单击其他窗口也会执行windowDeactivated()
,由最小化恢复会执行windowDeiconified()
和windowActivated()
,当前窗口为其他窗口时单击该窗口,也会执行windowActivated()
,窗口被关闭,则执行windowClosed()
.
方法参数:WindowEvent e
选项事件的处理
单选按钮、复选框、下拉列表、列表框、菜单中每个选项或菜单项都可以使用选项事件进行处理。
接口:ItemListener
,每当选择某个选项,便会自动执行itemStateChanged()
方法,该方法的参数为ItemEvent
。其getItem()
方法可以获得选项对应的字符串,getStateChange()
方法可以获得选项是选中(值为ItemEvent.SELECTED
)还是未选中(值为ItemEvent.DESELECTED
)。
添加监听:.addItemListener(this)
;
动作事件的处理(文本框)
ActionListener
除了用于鼠标单击按钮外,单行文本框中的回车、列表框中双击选择某个选项也可以用其处理。
import java.awt.*;
import java.awt.event.*;
class NZAC implements ActionListener{
TextField t = new TextField(“you can enter here”,35);
t.addActionListener(this); //即单行文本框可以自动监听。
...
public void actionPerformed(ActionPerformed e){
String s = t.getText();
System.out.println(s);
}
}
注意:对于多行文本框TextArea
,不能自动监听,可以添加按钮来实现检查和提交功能。
多个事件处理器
如果对一个组件添加多个事件处理器,则需要对每一个处理器创建一个类。
Adapter
类
事件处理器实现的接口中往往有多个方法要实现,而某个具体程序用到的可能只是其中的一个,但实现接口时根据接口的语法规则必须把所有方法都实现,因此程序中不使用的方法要写空语句。
为了简化程序,java中预定义了一些特殊的类,这些类应经实现了相应的接口,方法中已经写上空语句,使用时只要将事件处理器作为子类(使用extends
,而不是implements
)即可。命名规则:只要将接口中的Listener
改为Adapter
即可。对于只有一个方法需要实现的接口,没有Adapter
。
通过鼠标双击直接运行java程序
DOS下可以用javac *.java
来编译java文件,使用java 类名 来执行程序。
制作jar文件
双击直接运行java程序。
比如有NZFrame.java一文件。
javac NZFrame.java
编译生成MyFrame.class
然后做一个配置文件,随意起一个文件名如conf.txt,该文件中输入一行内容:
Main-Class: NZFrame
注意:文件开头顶格,不可有空行空格,Main-Class:
后有一空格。该配置文件给出了双击jar文件时运行其中的哪个类。
然后输入如下命令制作jar文件:
jar cmf conf.txt NZFrame.jar *.class
这样将创建MyFrame.jar,以后只要双击即可执行。
使用批处理制作
运行jar文件
java –jar NZFrame.jar