public class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
一个可表示的存储区域
class Person
{
int age;
String name;
void sayHello()
}
Person p = new Person()
将属性和行为封装在类中,程序定义很多类
class Person
{
private int age;
public int getAge(){
return age;}
public void setAge(int a){
age=a;}
void sayHello(){
…}
}
父类和子类之间共享数据和方法
父类
class person
{
int age;
String name;
void sayHello(){
…}
}
子类
class Student extends Person
{
String school;
double score;
void meetTeacher(){
…}
}
子类便继承了父类的那些功能属性,并且具有子类这些更新的属性
好处:
不同的对象收到一个调用方法可产生完全不同的效果
老师和学生虽然都被一个函数调用却能产生两种不同的打招呼方式
foo(Person p) {
p.sayHello();}
foo(new Student());
foo(new Teacher());
class是主体
public类名与文件同名
main()写法固定
System.out.print 及println及printf
public class HelloWorldApp
{
public static void main(String args[])
{
System.out.println(“Hello World!”);
}
}
import表示导入
extends JApplet表示继承 Applet或JApplet都可以
有paint()方法,表示如何绘制
没有main()方法
import java.awt.*;
import java.applet.*;
import javax.swing.*;
public class HelloWorldApplet extends JApplet
{
public void paint(Graphics g)
{
g.drawString(“Hello World!”,20,20);
}
}
//这个.java不能单独运行
//要配合html使用
<HTML>
<HEAD><TITLE> An Applet</TITLE></HEAD>
<BODY>
<applet code= “HelloWorldApplet.class"
width=200 height=40 background=white>
</applet>
</BODY>
</HTML>
转换为字节码(bytecode)文件,扩展名.class
(.class文件中包含java虚拟机的指令)
编译使用JDK工具javac.exe
javac Hello.java
执行.class文件中的指令的过程
java Hello
不能写成java Hello.class
在HTML中嵌入Applet
使用标签
javac 编译
java 运行(控制台及图形界面程序)
javaw运行图形界面程序
appletViewer运行apple程序
jar 打包工具
javadoc生成文档
javap 查看类信息及反汇编
编译javac A.java
打包jar cvfm A.jar A.man A.class
c表示create,v表示显示详情verbose,f表示指定文件名,m表示清单文件
运行java-jar A.jar
其中A.man是清单文件(manifest),内容如下:
manifest-Version:1.0
Class-Path:.
Main-Class:A
清单文件可以任意命名,常见的使用MANIFEST.MF
Javadoc -d目录名xxx.java
/** */这其中可以用一下标记
@auther对类说明 标记开发该类模块的作者
@version对类的说明 标明该类模块的版本
@see 对类,属性,方法的说明 参考转向,也就是相关主题
@param 对方法的说明 对方法中某参数的说明
@return 对方法的说明 对方法返回值的说明
@exception 对方法的说明 对方法可能抛出的异常进行说明
import java.util.Scanner;
class ScannerTest
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
System.out.print(“请输入一个数”);
int a = scanner.nextInt();
System.out.printf(“%d的平方是%d\n”,a,a*a);
}
}
System.in.read()
System.out.print()及println,printf 类似于C语言
char c = ‘ ’;
System.out.print(“PPlease input a char:”)
try
{
c = (char) System.in.read();
}
catch(IOException e){
}
System.out.println(“You have entered:” + c);
try
{
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in();
s = in.readLine();
}
catch(IOExeption e){
}
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
System.out.print(“Please input an int:”);
s = in.readLine();
n = Integer.parseInt(s);
//如果是double类型则为Double.parseDouble(s)
使用文本框对象TextField获取输入数据
使用标签对象Label或文本框对象输出数据
使用命令按钮Button来执行命令
通过Frame创建自己的用户界面,在构建AppFrame时,设定该Frame大小,并用setVisible(true)方法显示出来
setLayout(new FlowLayout());
add(in);
add(btn);
add(out);
btn.addActionListener(new BtnActionAdapter());
class BtnActionAdapter implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String s = in.getText();
double d = Double.parseDouble(s);
double sq = Math.sqrt(d);
out.setText( d + “的平方根是:” + sq);
}
}
//Java8后可简化为:
btn.addAcitonListener(e->{
String s = in.getText();
double d = Double.parseDouble(s);
double sq = Math.sqrt(d);
out.setText( d + “的平方根是:” + sq);
});
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class AppGraphInOut {
public static void main(String args[]) {
new AppFrame();//在main里面构建一个Frame对象
}
}
class AppFrame extends JFrame {
JTextField in = new JTextField(10);
JButton btn = new JButton("求平方");
JLabel out = new JLabel("用于显示结果的标签");
public AppFrame() {
setLayout(new FlowLayout());
getContentPane().add(in);//流式内容
getContentPane().add(btn);
getContentPane().add(out);
btn.addActionListener(new BtnActionAdapter());
setSize(400, 100);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
}
class BtnActionAdapter implements ActionListener {
public void actionPerformed(ActionEvent e) {
String s = in.getText();
double d = Double.parseDouble(s);
double sq = d * d;
out.setText(d + "的平方是:" + sq);
}
}
}
AppletInOut.java
在init()中:
add(xxx)加入对象
btn.addActionListener 处理事件
actionPerformed()函数 具体处理事件
import javax.swing.*;
import java.awt.*;
public class AppletInOut8 extends JApplet {
JTextField in = new JTextField(10);
JButton btn = new JButton("求平方根");
JLabel out = new JLabel("用于显示结果的标签");
public void init() {
setLayout(new FlowLayout());
add(in);
add(btn);
add(out);
btn.addActionListener(e -> {
String s = in.getText();
double d = Double.parseDouble(s);
double sq = Math.sqrt(d);
out.setText(d + "的平方根是:" + sq);
});
}
}
import javax.swing.*;
import java.awt.*;
public class AppAppletInOut extends JApplet {
public static void main(String args[]) {
JFrame frame = new JFrame();
AppAppletInOut app = new AppAppletInOut();
app.init();
frame.getContentPane().add(app);
frame.setSize(400, 100);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//关闭窗口
frame.setVisible(true);
}
JTextField in = new JTextField(10);
JButton btn = new JButton("求平方根");
JLabel out = new JLabel("用于显示结果的标签");
public void init() {
setLayout(new FlowLayout());
add(in);
add(btn);
add(out);
btn.addActionListener(e -> {
String s = in.getText();
double d = Double.parseDouble(s);
double sq = Math.sqrt(d);
out.setText(d + "的平方根是:" + sq);
});
}
}
变量在栈,赋值时复制的是值
数值型
字符型:char
布尔型:boolean
public class BooleanTest {
public static void main(String args[]) {
boolean a = false;
boolean b = true;
System.out.println(a + " " + b);
}
}
变量引用到堆,类似指针,赋值时复制的是引用
每个字符占两个字节 char c = ‘\u0061’
八进制:0开头,012
十六进制:0x或0X开头,0x12
二进制:0b或0B开头,0b00010010
&& 第一个操作符为假则不判断第二个操作数
|| 第一个操作数为真则不判定第二个操作数
if((d != NULL) && (d.day > 31))
{
//则它只会先判断第一个是否成立,在第一个成立的前提下才去看第二个
}
public class LeapYear {
public static void main(String args[]) {
int year = 2003;
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
System.out.println(year + " is a leap year.");
}
else {
System.out.println(year + " is not a leap year.");
}
}
}
左移:a<最低位空出的b位补0
带符号右移:a>>b;
最高位空出的b位补原来的符号位
无符号右移:a>>>b;
最高位空出的b位补0
public class BitwiseOperators {
public static void main(String args[]) {
int a = 0b1100;
int b = 0b1010;
print("a ", a);
print("b ", b);
print("a&b", a & b);
print("a|b", a | b);
print("a^b", a ^ b);
print("~a", ~a);
print("a<<2", a << 2);
print("a>>2", a >> 2);
print("a>>>2", a >>> 2);
}
static void print(String prefix, int n) {
String s = Integer.toBinaryString(n);
while (s.length() < 4) {
//长度不够就补0
s = "0" + s;
}
System.out.println(prefix + " " + s);
}
}
public class GradeLevel {
public static void main(String args[]) {
char grade = 'C';
switch (grade) {
case 'A':
System.out.println(grade + " is 85~100");
break;
case 'B':
System.out.println(grade + " is 70~84");
break;
case 'C':
System.out.println(grade + " is 60~69");
break;
case 'D':
System.out.println(grade + " is <60");
break;
default:
System.out.println("Input Error");
}
}
}
lable1:{
lable2: {
lable3: {
break label2;
}
}
}
//从里层循环直接跳出二至多层
public class Rnd_36_7
{
public static void main(String args[])
{
int a[] = new int[7];
for (int i = 0; i < a.length; i++)
{
one_num:
while (true)
{
a[i] = (int) (Math.random() * 36) + 1;
for (int j = 0; j < i; j++)
{
if (a[i] == a[j])
{
continue one_num;
}
break;
}
}
}
for (int num : a)
{
System.out.println(num + " ");
}
System.out.println();
}
}
public class Prime100Continue
{
public static void main(String args[])
{
System.out.println("****100--200的质数****");
int n = 0;
outer:
for (int i = 0; i < 200; i += 2)
{
//外层循环
for (int j = 2; j < 2; j++)
{
//内层循环
if (i % j == 0)
{
//不是质数,则继续外层循环
continue outer;
}
}
System.out.println(" " + i);//显示质数
n++;//计算个数
if (n < 10)
{
//未满十个数不换行
continue;
}
System.out.println();
n = 0;
}
System.out.println();
}
}
import javax.swing.*;
import java.awt.*;
public class AutoScore extends JFrame
{
public static void main(String [] argv)
{
JFrame frame = new AutoScore();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,600);
frame.setVisible(true);
}
public AutoScore()
{
init();
setSize(400, 350);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public void init()
{
setLayout(null);//手动布局
setSize(400, 350);
btnNew.setLabel("出题");
getContentPane().add(btnNew);
btnNew.setBackground(java.awt.Color.lightGray);
btnNew.setBounds(36, 96, 98, 26);
btnJudge.setLabel("判分");
getContentPane().add(btnJudge);
btnJudge.setBackground(java.awt.Color.lightGray);
btnJudge.setBounds(216, 96, 94, 25);
lblA.setText("text");
getContentPane().add(lblA);
lblA.setFont(new Font("Dialog", Font.PLAIN, 24));
lblA.setBounds(36, 24, 36, 36);
lblOp.setText("text");
getContentPane().add(lblOp);
lblOp.setFont(new Font("Dialog", Font.PLAIN, 24));
lblOp.setBounds(72, 24, 36, 36);
lblB.setText("text");
getContentPane().add(lblB);
lblB.setFont(new Font("Dialog", Font.PLAIN, 24));
lblB.setBounds(108, 24, 33, 36);
label5.setText("=");
getContentPane().add(label5);
label5.setFont(new Font("Dialog", Font.PLAIN, 24));
label5.setBounds(168, 24, 33, 36);
getContentPane().add(txtAnswer);
txtAnswer.setFont(new Font("Dialog", Font.PLAIN, 24));
txtAnswer.setBounds(216, 24, 85, 42);
listDisp.setFont(new Font("Dialog", Font.PLAIN, 24));
getContentPane().add(listDisp);
listDisp.setBounds(36, 144, 272, 106);
SymAciton lSymAction = new SymAciton();
btnNew.addActionListener(lSymAction);
btnJudge.addActionListener(lSymAction);
}
java.awt.Button btnNew = new java.awt.Button();
java.awt.Button btnJudge = new java.awt.Button();
java.awt.Label lblA = new java.awt.Label();
java.awt.Label lblOp = new java.awt.Label();
java.awt.Label lblB = new java.awt.Label();
java.awt.Label label5 = new java.awt.Label();
java.awt.TextField txtAnswer = new java.awt.TextField();
java.awt.List listDisp = new java.awt.List(0);
class SymAciton implements java.awt.event.ActionListener
{
//接口
public void actionPerformed(java.awt.event.ActionEvent event)
{
//方法
Object object = event.getSource();
if (object == btnNew)
{
btnNewActionPerformed(event);
}
else
{
btnJudgeActionPerformed(event);
}
}
}
void btnNewActionPerformed(java.awt.event.ActionEvent event)
{
a = (int) (Math.random() * 9 + 1);
b = (int) (Math.random() * 9 + 1);
int c = (int) (Math.random() * 4);
switch (c)
{
case 0:
op = "+";
result = a + b;
break;
case 1:
op = "-";
result = a - b;
break;
case 2:
op = "*";
result = a * b;
break;
case 3:
op = "/";
result = a / b;
break;
}
lblA.setText("" + a);
lblB.setText("" + b);
lblOp.setText("" + op);
txtAnswer.setText("");
}
int a = 0, b = 0;
String op = "";
double result = 0;
void btnJudgeActionPerformed(java.awt.event.ActionEvent event)
{
String str = txtAnswer.getText();
double d = Double.valueOf(str).doubleValue();
String disp = "" + a + op + b + "=" + str + "";
if (d == result)
{
disp += "Yes";
}
else
{
disp += "No";
}
listDisp.add(disp);
}
}
import javax.swing.*;
import java.awt.*;
public class Circle99Frame extends JFrame
{
public static void main(String[] argv)
{
JFrame frame = new Circle99Frame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setVisible(true);
}
public void paint(Graphics g)
{
g.drawString("circle 90", 20, 20);
int x0 = getSize().width / 2;
int y0 = getSize().height / 2;
for (int r = 0; r < getSize().height / 2; r += 10)
{
g.setColor(getRandomColor());
g.drawOval(x0 - r, y0 - r, r * 2, r * 2);
}
}
Color getRandomColor()
{
return new Color(
(int) (Math.random() * 255),
(int) (Math.random() * 255),
(int) (Math.random() * 255)
);
}
}
int a[] = new int[3];//分配空间
a[0] = 3;
a[1] = 9;
a[2] = 8;
MyDate []dates = new MyDate[3];
dates[0] = new MyDate(22,7,1964);
dates[1] = new MyDate(1,1,2000);
dates[2] = new MyDate(22,12,1964);
int[] a = {
3,9,8}; 或 int[] a = new int[] {
3,9,8}
MyDate[] dates = {
new MyDate(22,7,1964),new MyDate(1,1,2000),new MyDate(22,12,1964)
};
可以方便的处理数组,集合中各元素
int[] ages = new int[10];
for ( int age : ages )
{
//这种语句是只读式遍历
System.out.println(age);
}
数组复制System.arraycopy提供了数组元素复制功能:
System.arraycopy(source,1,dest,0,source.Length);
将source数组中第1个元素开始
复制到dest数组中第0个开始,一共复制source.Length这么长
二维数组是数组的数组
int [][] a = {
{
1,2},{
3,4,0,9},{
5,6,7} };
int [][] t = new int [3][];
t[0] = new int [2];//开的数组不一定是完整的矩形
t[1] = new int [4];
t[2] = new int [3];
class Person
{
String name;
int age;
void sayHello()
{
System.out.println(“Hello! My name is” + name);
}
}
Person( String n,int a)
{
name = n;
age = a;
}
方法有相同的名字,编译时能识别出来
签名不同:参数个数不同或参数类型不同
通过方法重载可以实现多态
在方法及构造方法中可以使用this.+字段来调用本局部变量的值
字段的继承
字段的隐藏
子类重新定义一个与从父类那里继承来的域变量完全相同的变量,称为域的隐藏
字段的添加
在定义子类时,加上新的域变量,据可以使子类比父类多一些属性
class Student extends Person
{
String school;
int score;
}
方法的继承
父类的非私有方法也可以被子类自动继承
Student自动继承Person的方法sayHello和isOlderThan
方法的覆盖(Override)(修改)
子类也可以重新定义与父类同名的方法,实现对父类方法的覆盖
@Override的使用
@Override
void sayHello()
{
System.out.println("Hello! My name is" + name + ".My school is " + school);
}
通过方法的覆盖,能够修改对象同名方法的具体实现方法
方法的添加
子类可以新加一些方法,以针对子类实现相应的功能
在类Student中,加入一个方法,对分数判断:
boolean isGoodStudent()
{
return score >= 90;
}
方法的重载
一个类中可以有几个同名的方法,这称为方法的重载(Overload)
同时还可以重载父类的同名方法.与覆盖方法不同的是,重载不要求参数类型列表相同
重载的方法实际是新加的方法
在类Student中,重载一个名为sayHello的方法:
void sayHelo(Student another)
{
System.out.println("Hi!");
if( school.quals( another.school ))
{
System.out.println(" Schoolmates ");
}
}
使用super访问父类的域和方法
由于继承,使用this可以访问父类的域和方法
但有时为了明确地指明父类的域和方法,就要用关键字super
父类Student有一个域age,在子类Student中用age,this.age,super.age来访问age是完全一样的
void testThisSuper()
{
int a;
a = age;
a = this.age;
a = super.age;
}
有时需要使用super以区别同名的域与方法
使用super可以访问被子类所隐藏了的同名变量
当覆盖父类的同名方法的同时,又要调用父类的方法,就必须使用super
void sayHello()
{
super.sayHello();
System.out.println("My school is" + school);
}
使用父类的构造方法
构造方法是不能继承的
比如,父类Person有一个构造方法Person(String,int)不能说子类Student也自动有一个构造方法Student(String,int)
但是,子类在构造方法中,可以用super来调用父类的构造方法
Student(String name,int age,String school)
{
super(name,age);
this.school=school;
}
使用时super只能放在第一句
public static void main( String [] args )
{
Person p = new Person("Liming",50);//正常情况
Student s = new Student("Wangqiang",20,"PKU");//正常情况
Person p2 = new Student("Zhangyi",18,"THU");
Student s2 = (Student) p2;
Student s3 = (Student) p;
p.sayHello(s);
Person [] manypeople = new Person[100];
manypeople[0] = new Person("Li",18);
manypeople[1] = new Student("Wang",18,"PKU");
}
package pkg1[.pkg2[.pkg3…]];
import package
public private
同一个类中 | 同一个包中 | 不同包中的子类 | 不同包中的非子类 | |
---|---|---|---|---|
private | yes | |||
默认 | yes | yes | ||
protected | yes | yes | yes | |
public | yes | yes | yes | yes |
abstract
基本含义 | 修饰类 | 修饰成员 | 修饰局部变量 | |
---|---|---|---|---|
static | 静态的,非实例的,类的 | 可以修饰内部类 | yes | |
final | 最终的,不可改变的 | yes | yes | yes |
abstract | 抽象的,不可实例化的 | yes | yes |
static字段
class Person
//此时的totalNum代表人类的总人数,他与具体对象实例无关
//从某种意义上讲,他可以用来表示全局变量,属于整个类的
{
static long totalNum;
int age;
String Name;
}
final
abstract类
接口,某种特定的约定
面向接口编程
interface Collection
{
void add(Object obj);
void delete(Object obj);
Object find(Object obj);
int size();
}
enum Light{
Red, Yellow, Green}
Light light = Light.Red;
swtch(light)
{
case Red:
break;
}
Java中的枚举是用class来实现的,可以复杂的使用
[public][abstract|final] class className[extends superclassName]
[implemrnts InterfaceNameList]
{
//类声明
[public|protected|private][static][final][transient][volatile] type variableName;//成员变量生命,可为多个
[public|protected|private][static][final|abstract][native][synchronized]
return Type methodName([paramList])//方法定义及实现,可为多个
[throws exceptionList]
{
statements
}
}
[public] interface InterfaceName [extends superInterfaceList]
{
//接口声明
type constantName = value;//常量声明,可为多个
return TypeMethodName([paraList]);//方法声明,可为多个
}
className([paramlist])
{
}
public static void main(String args[])
{
}
protected void finalize()throws throwable
{
}
package packageName;//指定文件中的类所在的包,0个或1个
import packageName.[className|*];//指定引入的类,0个或多个
public classDefinition//属性为public的类定义,0个或1个
interfaceDefinition and class Definition//接口或类定义,0个或多个
源文件的名字必须与属性为public的类的类名完全相同
在一个.java文件中,package语句和public类最多只能有1个
基本类型:其值直接cunyu 变量中
引用型的变量除占据一定的内存空间外,它所引用的对象实体(由new创建)也要占据一定空间
public class MyDate {
private int day;
private int month;
private int year;
public MyDate(int y, int m, int d) {
year = y;
month = m;
day = d;
}
void addYear() {
year++;
}
public void display() {
System.out.println(year + '-' + month + '-' + day);
}
public static void main(String args[]) {
MyDate m = new MyDate(2003, 9, 22);
MyDate n = m;
n.addYear();
m.display();
n.display();
}
}
//由于是new出来的变量,所以是一个引用的对象,故改变其中的一个会影响到所有的
前者是在类中,后者是方法中定义的变量或方法的参变量
从内存角度看
存储位置,字段变量为对象的一部分,存在于堆中,局部变量存在于栈中。
生命周期不同
初始值:字段变量可以自动赋初值,局部变量则须显式赋值
class Test()
{
int a;
void m(){
int b;
System.out.println(b);//编译不能通过,需要初始化
}
}
从语法角度来看
调用方法时,要传递参数.在传递参数时,Java是值传递,即,是将表达式的值复制给形式参数.
对于引用型变量,传递的值是引用值,而不是复制对象实体(可以改变对象的属性)
public class TransByValue {
public static void main(String[] args) {
int a = 0;
modify(a);
System.out.println(a);//0
int[] b = new int[1];
modify(b);
System.out.println(b[0]);//1
}
public static void modify(int a) {
a++;//仅仅是传了个参数进来,对外面的a不影响
}
public static void modify(int[] b) {
b[0]++;
b = new int[5];
}
}
方法的返回:
Object getNewObject()
{
Object obj = new Object();
return obj;
}
调用时:object p = GetNewObject();
是把派生类型当作基本类型处理
Person p = new Student();
void fun(Person p){
...}
fun(new Person());
用虚方法调用,可以实现运行时的多态
import java.awt.*;
public class TestVirtualInvoke {
static void doStuff(Shape s) {
s.draw();
}
public static void main(String[] args) {
Circle c = new Circle();
Triangle t = new Triangle();
Line l = new Line();
doStuff(c);
doStuff(t);
doStuff(l);
}
}
class Shape {
void draw() {
System.out.println("Shape Drawing");
}
}
class Circle extends Shape {
void draw() {
System.out.println("Draw Circle");
}
}
class Triangle extends Shape {
void draw() {
System.out.println("Draw Three Lines");
}
}
class Line extends Shape {
void draw() {
System.out.println("Draw Line");
}
}
变量instanceof类型
结果是boolean值
class InstanceOf {
public static void main(String[] args) {
Object[] things = new Object[3];
things[0] = new Integer(4);
things[1] = new Double(3.14);
things[2] = new String("2.09");
double s = 0;
for (int i = 0; i < things.length; i++) {
if (things[i] instanceof Integer)//判断其是不是个整数
s += ((Integer) things[i]).intValue();
else if (things[i] instanceof Double)//判断其是不是个双精度
s += ((Double) things[i]).doubleValue();
}
System.out.println("sum=" + s);
}
}
Java中,普通方法是虚方法
但static,private方法不是虚方法调用
static,private与虚方法编译后用的指令是不同的
class JavaP3methods {
void f() {
}
private void p() {
}
static void s() {
}
public static void main(String... argv) {
JavaP3methods obj = new JavaP3methods();
obj.f();
obj.p();
obj.s();
}
}
class TestStaticInvoke {
static void doStuff(Shape s) {
s.draw();
}
public static void main(String[] args) {
Circle c = new Circle();
Triangle t = new Triangle();
Line l = new Line();
doStuff(c);//由于是定义的是static类所以只跟你定义的类型有关系
doStuff(t);//此处都是跟shape有关
doStuff(l);
Shape s = new Circle();
doStuff(s);//声明了shape类故只能输出ShapeDrawing
s.draw();
Circle c2 = new Circle();
c2.draw();//声明了circle类之后调用了其本身的方法故输出DrawCircle
}
}
class Shape {
static void draw() {
System.out.println("Shape Drawing");
}
}
class Circle extends Shape {
static void draw() {
System.out.println("Draw Circle");
}
}
class Triangle extends Shape {
static void draw() {
System.out.println("Draw Three Lines");
}
}
class Line extends Shape {
static void draw() {
System.out.println("Draw Line");
}
}
/*
Shape Drawing
Shape Drawing
Shape Drawing
Shape Drawing
Shape Drawing
Draw Circle
*/
对象都有构造方法,如果没有,编译器加一个default构造方法
调用本类或父类的构造方法
如果没有this及super,则编译器自动加上super(),即调用直接父类不带参数的构造方法
因为必须令所有父类的构造方法都得到调用,否则整个对象的构造就可能不正确
class ConstructCallThisAndSuper {
public static void main(String[] args) {
Person p = new Graduate();//创建一个人p,他是一个研究生
}
}
class Person {
String name;
int age;
Person() {
}
Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("In Person(String,int)");
}
}
class Student extends Person {
String school;
Student() {
this(null, 0, null);
System.out.println("In Student()");
}
Student(String name, int age, String school) {
super(name, age);
this.school = school;
System.out.println("In Student(String,int,String)");
}
}
class Graduate extends Student {
String teacher = "";
Graduate() {
//super();加上与不加上都可,编译器会自动的加上super,因为他会继承父类
System.out.println("In Graduate()");
}
}
/*
会调用一系列的构造方法
In Person(String,int)
In Student(String,int,String)
In Student()
In Graduate()
*/
class A{
A(int a){
}
}
class B extends A{
B(String s){
//编译不能通过
}
}
编译器会自动调用
B(String s){
super();
}出错
解决方法:
A(){}
p = new Person(){
{
age = 18; name = "李明";}};
注意双括号
{语句}
在类中直接写,实例初始化,先于构造方法中的语句执行
static {语句}
静态初始化,在第一次使用这个类时执行,但其执行的具体时机是不确定的,但可以肯定的是:总是先于实例的初始化
class InitialTest {
public static void main(String[] args) {
new InitialTest2(6);
}
int n = 10; //step2
{
n++;
System.out.println("InitialTest..." + n);
}
static int x;
static {
x++;
System.out.println("static..." + x);
}
}
class InitialTest2 extends InitialTest {
InitialTest2(int a) {
//构造函数
this.a = a;
System.out.println("this.a=" + a);
}
int a;
{
System.out.println("InitialTest2..." + this.a);
}
static {
x++;
System.out.println("static2..." + x);
}
}
/*
先构造一个子类,但是static初始化先运行
然后运行实例初始化,最后在构造函数
static...1
static2...2
InitialTest...11
InitialTest2...0
this.a=6
*/
简单的说:先父类构造,再本类成员赋值,最后执行构造方法中的语句
class ConstructSequence {
public static void main(String[] args) {
Person p = new Student("李明", 18, "北大");
}
}
class Person {
String name = "未命名"; //step 2
int age = -1;
Person(String name, int age) {
super(); //step 1
//step 3
System.out.println("开始构造Person(),此时this.name=" + this.name + ",this.age=" + this.age);
this.name = name;
this.age = age;
System.out.println("Person()构造完成,此时this.name=" + this.name + ",this.age=" + this.age);
}
}
class Student extends Person {
String school = "未定学校"; //step2
Student(String name, int age, String school) {
super(name, age); //step 1
//step 3
System.out.println("开始构造Student(),此时this.name=" + this.name + ",this.age=" + this.age + ",this.school=" + this.school);
this.school = school;
System.out.println("Student()构造完成,此时this.name=" + this.name + ",this.age=" + this.age + ",this.school=" + this.school);
}
}
/*
开始构造Person(),此时this.name=未命名,this.age=-1
Person()构造完成,此时this.name=李明,this.age=18
开始构造Student(),此时this.name=李明,this.age=18,this.school=未定学校
Student()构造完成,此时this.name=李明,this.age=18,this.school=北大
*/
构造方法内部调用别的方法,这个方法恰好是个虚方法,结果如何?
class ConstructInvokeMetamorph {
public static void main(String[] args) {
Person p = new Student("李明", 18, "北大");
}
}
class Person {
String name = "未命名";
int age = -1;
Person(String name, int age) {
this.name = name;
this.age = age;
sayHello();
//在此时调用的函数为虚函数,是子类的函数,而此时学校的信息还没有复制好,会导致出现错误
}
void sayHello() {
System.out.println("我是一个人,我名叫:" + name + ",年龄为:" + age);
}
}
class Student extends Person {
String school = "未定学校";
Student(String name, int age, String school) {
super(name, age);
this.school = school;
}
void sayHello() {
System.out.println("我是学生,我名叫:" + name + ",年龄为:" + age + ",学校在:" + school);
}
}
/*
我是学生,我名叫:李明,年龄为:18,学校在:null
*/
垃圾回收,对象回收是由Java虚拟机的垃圾回收线程来完成的
为什么系统知道对象是否为垃圾:任何对象都有一个引用计数器,当其值为0时,说明该对象可以回收
System.gc()
方法,他是System类的static方法,它可以要求系统进行垃圾回收,但他仅仅只是‘建议’
Java中没有析构方法
但Object的finalize()
有类似功能
finalize()
方法protected void finalize() throws Throwable{}
子类的finalize()
方法
finalize()
方法释放系统资源finalize()
方法中应该调用父类的finalize()
方法,以保证父类的清理工作能够正常进行。由于finalize()
方法的调用时机不确定,所以一般不用finalize()
关闭打开的文件,清除一些非内存资源等工作需要进行处理可以使用tyr-with-resource语句
对于实现了java.lang.AutoCloseable的对象
try( Scanner scanner = new Scanner(...) ){
...
}
会自动调用其clode()方法,相当于
finally{
Scanner.close();
}
class TestInnerClass {
public static void main(String[] args) {
Parcel p = new Parcel();
p.testShip();
Parcel.Contents c = p.new Contents(33);//要加上外部的类名
Parcel.Destination d = p.new Destination("Hawii");
p.setProperty(c, d);
p.ship();
}
}
class Parcel {
private Contents c;
private Destination d;
class Contents {
//内部类
private int i;
Contents(int i) {
this.i = i;
}
int value() {
return i;
}
}
class Destination {
private String label;
Destination(String whereTo) {
label = whereTo;
}
String readLabel() {
return label;
}
}
void setProperty(Contents c, Destination d) {
this.c = c;
this.d = d;
}
void ship() {
System.out.println("move " + c.value() + " to " + d.readLabel());
}
public void testShip() {
c = new Contents(22);
d = new Destination("Beijing");
ship();
}
}
public class TestInnerThis {
public static void main(String args[]) {
A a = new A();
A.B b = a.new B();
b.mb(333);
}
}
class A {
private int s = 111;
public class B {
private int s = 222;
public void mb(int s) {
System.out.println(s); // 局部变量s
System.out.println(this.s); // 内部类对象的属性s
System.out.println(A.this.s); // 外层类对象属性s
}
}
}
内部类与类中的字段、方法一样是外部类的成员,它的前面也可以有访问控制符和其他修饰符
访问控制符:public,protected,默认及private。
外部类只能够使用public修饰或者默认
final,abstract
static修饰内部类,表明内部类实际是一种外部类
实例化static类时,在new前面不需要用对象实例变量
static类中不能访问其外部类的非static的字段及方法,既只能够访问static成员
static方法中不能访问非static的域及方法,也不能够不带前缀地new一个非static的内部类
class TestInnerStatic {
public static void main(String[] args) {
A.B a_b = new A().new B();
A a = new A();
A.B ab = a.new B();
Outer.Inner oi = new Outer.Inner();
//Outer.Inner oi2 = Outer.new Inner(); //!!!error
//Outer.Inner oi3 = new Outer().new Inner(); //!!! error
}
}
class A {
private int x;
void m() {
new B();
}
static void sm() {
//new B(); // error!!!!
}
class B {
B() {
x = 5;
}
}
}
class Outer {
static class Inner {
}
}
在一个方法中定义类,方法中的内部类
class TestInnerInMethod {
public static void main(String[] args) {
Object obj = new Outer().makeTheInner(47);
System.out.println("Hello World!" + obj.toString());
}
}
class Outer {
private int size = 5;
public Object makeTheInner(int localVar) {
final int finalLocalVar = 99;
class Inner {
public String toString() {
return (" InnerSize: " + size +
// " localVar: " + localVar + // Error!
" finalLocalVar: " + finalLocalVar
);
}
}
return new Inner();
}
}
class TestInnerAnonymous {
public static void main(String[] args) {
Object obj = new Outer().makeTheInner(47);
System.out.println("Hello World!" + obj.toString());
}
}
class Outer {
private int size = 5;
public Object makeTheInner(int localVar) {
final int finalLocalVar = 99;
return new Object() {
public String toString() {
return (" InnerSize: " + size +
" finalLocalVar: " + finalLocalVar
);
}
};
}
}
(){...}
(String s) -> s.length()
x -> x*x
() -> {System.out.println(“aaa”);}
大体相当于其他语言的 “匿名函数” 或 “函数指针”
在Java中它实际上是 “匿名类的一个实例”
Runnable dolt = new Runnable(){
public void run(){
System.out.println("aaa");
}
}
new Thread(dolt).start();
就可以写成
Runnable dolt = () -> System.out.println("aaa");
new Thread( dolt ).start();
甚至可以写为
new Thread(() -> System.out.println("aaa")).start();
例如:
写一个积分函数
double d = Integral( new Fun() {
public double fun(double x){
return Math.sin(x);
}
}, 0, Math.PI, 1e-5);
可以写为
double d = Integral( x-> Math.sin(x) , 0, Math.PI, 1e-5);
@FunctionalInterface
interface Fun {
double fun(double x);
}
public class LambdaIntegral {
public static void main(String[] args) {
double d = Integral(new Fun() {
public double fun(double x) {
return Math.sin(x);
}
}, 0, Math.PI, 1e-5);
d = Integral(x -> Math.sin(x),
0, Math.PI, 1e-5);
System.out.println(d);
d = Integral(x -> x * x, 0, 1, 1e-5);
System.out.println(d);
}
static double Integral(Fun f, double a, double b, double eps)// ���ּ���
{
int n, k;
double fa, fb, h, t1, p, s, x, t = 0;
fa = f.fun(a);
fb = f.fun(b);
n = 1;
h = b - a;
t1 = h * (fa + fb) / 2.0;
p = Double.MAX_VALUE;
while (p >= eps) {
s = 0.0;
for (k = 0; k <= n - 1; k++) {
x = a + (k + 0.5) * h;
s = s + f.fun(x);
}
t = (t1 + h * s) / 2.0;
p = Math.abs(t1 - t);
t1 = t;
n = n + n;
h = h / 2.0;
}
return t;
}
}
能写成lambda的接口要求包含最多只能有一个抽象函数
@FunctionalInterface
interface Fun{
double fun( double x );
}
将基本类型包装成Object引用类型
Interger包含了八类
Boolean,Byte,Short,Character,Integer,Long,Float,Double
装箱Integer I = 10;
拆箱int i = I;
主要方便用于集合中
Object [] are = { 1, “aaa”};
enum Light {Red, Yellow, Green };
Light light = Light.Red;
class Light extends java.lang.Enum
可以在enum定义体中,添加字段,方法,构造方法
enum Direction
{
EAST("东", 1),
SOUTH("南", 2),
WEST("西", 3),
NORTH("北", 4);
private Direction( String desc, int num){
this.desc = desc;
this.num = num;
}
private String desc;
private int num;
public String getDesc(){
return desc;}
public int getNum(){
return num;}
}
在各种语法要素上加上附加信息
都是java.lang.annotation.Annotation
的子类
常用的注解
@Override 表示覆盖父类的方法
@Deprecated 表示过时的方法
@SuppressWarnings 表示让编译器不产生警告
自定义注解,比较复杂
public @interface Auther{
String name();
}
引用实质就是指针
但是它是受控制的,安全的
*(p+5)
传地址 -> 对象
void swap(int x, int =y) {int t = x; x = y; y =t; }
int a = 8, b = 9; swap( a, b);
指针运算 -> 数组
*(p + 5)
则可以用args[5]
函数指针 -> 接口,Lambda表达式
求积分,线程,回调函数,时间处理
指向结点的指针 -> 对象的引用
class Node{
object data;
Node next;
}//链表
import java.io.IOException;
public class List {
private Node Head = null;
private Node Tail = null;
private Node Pointer = null;
private int Length = 0;
public void deleteAll() {
Head = null;
Tail = null;
Pointer = null;
Length = 0;
}
public void reset() {
Pointer = null;
}
public boolean isEmpty() {
return (Length == 0);
}
public boolean isEnd() {
if (Length == 0) throw new java.lang.NullPointerException();
else if (Length == 1) return true;
else return (cursor() == Tail);
}
public Object nextNode() {
if (Length == 1) throw new java.util.NoSuchElementException();
else if (Length == 0) throw new java.lang.NullPointerException();
else {
Node temp = cursor();
Pointer = temp;
if (temp != Tail) return (temp.next.data);
else throw new java.util.NoSuchElementException();
}
}
public Object currentNode() {
Node temp = cursor();
return temp.data;
}
public void insert(Object d) {
Node e = new Node(d);
if (Length == 0) {
Tail = e;
Head = e;
} else {
Node temp = cursor();
e.next = temp;
if (Pointer == null) Head = e;
else Pointer.next = e;
}
Length++;
}
public int size() {
return (Length);
}
public Object remove() {
Object temp;
if (Length == 0) throw new java.util.NoSuchElementException();
else if (Length == 1) {
temp = Head.data;
deleteAll();
} else {
Node cur = cursor();
temp = cur.data;
if (cur == Head) Head = cur.next;
else if (cur == Tail) {
Pointer.next = null;
Tail = Pointer;
reset();
} else Pointer.next = cur.next;
Length--;
}
return temp;
}
private Node cursor() {
if (Head == null) throw new java.lang.NullPointerException();
else if (Pointer == null) return Head;
else return Pointer.next;
}
public static void main(String[] args) throws IOException{
List a = new List();
for (int i = 1; i <= 10; i++) a.insert(new Integer(i));
System.out.println(a.currentNode());
while (!a.isEnd()) System.out.println(a.nextNode());
a.reset();
while (!a.isEnd()) {
a.remove();
}
a.remove();
a.reset();
if (a.isEmpty()) System.out.println("There is no Node in List n");
System.out.println("You can press return to quitn");
try {
System. in .read();
} catch(IOException e) {
}
}
}
class Node {
Object data;
Node next;
Node(Object d) {
data = d;
next = null;
}
}
使用JNI
Java Native Interface (JNI)
它允许JAVA代码和其他语言写的代码交互
==
基本类型
数值类型:转换后比较
浮点数,最好不直接==
Double.NAN == Double.NAN结果为false
boolean型无法与int相比较
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println( i==j );//false,因为对象是两个
Integer m = 10;
Integer n = 10;
System.out.println( m==n );//true,因为对象有缓存
Integer p = 200;
Integer q = 200;
System.out.println( p==q );//false,因为对象是两个
-128 127
枚举类型
内部进行了唯一实例化,所以可以直接判断
引用对象
String对象
判断相等,一定不要用==,要用equals
但是字符串常量(String literal)及字符串常量会进行内部话(interned),相同的字符串常量是==的
class TestStringEquals{
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.println( hello == "Hello"); //true
System.out.println( Other.hello == hello ); //true
System.out.println( hello == ("Hel"+"lo") ); //true
System.out.println( hello == ("Hel"+lo) ); //false
System.out.println( hello == new String("Hello")); //false
System.out.println( hello == ("Hel"+lo).intern()); //true
}
}
class Other {
static String hello = "Hello"; }
try{
语句组
}catch(Exception ex){
异常处理语句组;
}
import java.io.*;
public class ExceptionForNum
{
public static void main(String[] args)
{
try{
BufferedReader in = new BufferedReader(
new InputStreamReader( System.in ) );
System.out.print("Please input a number: ");
String s = in.readLine();
int n = Integer.parseInt( s );
}catch(IOException ex){
ex.printStackTrace();
}catch(NumberFormatException ex){
ex.printStackTrace();
}
}
}
抛出异常
throw 异常对象;
捕获异常
try{
语句组
}catch(异常类名 异常形式参数名){
异常处理语句组;
}catch(异常类名 异常形式参数名){
异常处理语句组;
}finally{
异常处理语句组;
} 其中,catch语句可以0至多个,可以没有finally语句
Throwable
Error:JVM的错误
Exception:异常,一般所说的异常是指Exception及其子类
构造方法
public Exception();
public Exception(String message);
Exception(String message, Throwable cause);
方法
getMessage()
getCause()
printfStackTrace()
子类异常排在父类前面
无论是否有异常都要执行,即使其中有break等语句
class JavaPTryCatchFinally {
public static void main(String[] args) {
int a = 100;
try {
a = 200;
} catch (IndexOutOfBoundsException ex) {
a = 300;
} catch (Exception ex) {
a = 400;
} finally {
a = 500;
}
a = 600;
}
}
public class TestTryFinally {
public static String output = "";
public static void foo(int i) {
try {
if (i == 1) {
throw new Exception();
}
output += "1";
} catch(Exception e) {
output += "2";
return;
} finally {
output += "3";
}
output += "4";
}
public static void main(String args[]) {
//foo(0);
//System.out.print(output + " ");
foo(1);
System.out.println(output);
}
}
Exception分两种
受检的异常,要求明确进行语法处理
要么捕(catch)
要么抛(throws),在方法的签名后面用throws ****来
import java.io.*;
public class ExceptionTrowsToOther{
public static void main(String[] args){
try{
System.out.println("====Before====");
readFile();
System.out.println("====After====");
}catch(IOException e){
System.out.println(e); }
}
public static void readFile()throws IOException {
FileInputStream in=new FileInputStream("myfile.txt");
int b;
b = in.read();
while(b!= -1) {
System.out.print((char)b);
b = in.read();
}
in.close();
}
}
try(类型 变量名 = new 类型()){
...
}
将会添加了finally {
变量.close();
}
import java.io.*;
class TryWithResourcesTest {
public static void main(String ... args)
throws IOException
{
String path = "c:\\aaa.txt";
System.out.println( ReadOneLine1( path ) );
System.out.println( ReadOneLine2( path ) );
}
static String ReadOneLine1(String path){
BufferedReader br=null;
try {
br=new BufferedReader(new FileReader(path));
return br.readLine();
} catch(IOException e) {
e.printStackTrace();
} finally {
if(br!=null){
try{
br.close();
}catch(IOException ex){
}
}
}
return null;
}
static String ReadOneLine2(String path)
throws IOException
{
try(BufferedReader br= new BufferedReader(new FileReader(path))){
return br.readLine();
}
}
}
public class ExceptionCause {
public static void main(String [] args) {
try
{
BankATM.GetBalanceInfo( 12345L);
}catch(Exception e) {
System.out.println("something wrong: " + e);
System.out.println("cause:" + e.getCause());
}
}
}
class DataHouse {
public static void FindData( long ID)
throws DataHouseException
{
if( ID>0 && ID<1000)
System.out.println( "id: " + ID );
else
throw new DataHouseException("cannot find the id");
}
}
class BankATM{
public static void GetBalanceInfo( long ID)
throws MyAppException
{
try
{
DataHouse.FindData(ID);
}catch (DataHouseException e) {
throw new MyAppException("invalid id",e);
}
}
}
class DataHouseException extends Exception {
public DataHouseException( String message ) {
super(message);
}
}
class MyAppException extends Exception {
public MyAppException (String message){
super (message);
}
public MyAppException (String message, Exception cause) {
super(message,cause);
}
}
assert格式:
再调试程序时
如果表达式不为true,则程序会产生异常,并输出相关的错误信息
class Assertion {
public static void main(String[] args) {
assert hypotenuse(3,4)==5 : "算法不正确";
}
static double hypotenuse( double x, double y ){
return Math.sqrt( x*x + y*y + 1);
}
}
@Test来标注测试函数
在测试中常用的语句如下:
fail(信息);//表示程序出错
assertEqauls(参数1, 参数2);//表示程序要保证两个参数相等
assertNull(参数);//表示参数要为null
@Test
public void testSum2(){
HelloWorld a = new HelloWorld();
assertEquals(a.sum(0,100),100);
//fail("Not yet implemented");
}
String类
创建之后不会再做修改和变动,即immutable
StringBuffer,StringBuilder类
创建之后允许再做更改和变化
其中StringBuilder是JDK1.5增加的,它是非线程安全的
特别注意,在循环中使用String+=可能会带来效率的问题
import java.util.*;
class StringAndStringBuffer
{
public static void main(String[] args)
{
String a = "a";
String s = "";
StringBuffer sb = new StringBuffer();
final int N = 10000;
long t0 = System.currentTimeMillis();
for( int i=0; i<N; i++) s+=a;
long t1 = System.currentTimeMillis();
for( int i=0; i<N; i++) sb.append(a);
long t2 = System.currentTimeMillis();
System.out.println(t1-t0);
System.out.println(t2-t1);
}
}
String类对象保存不可修改的Unicode字符序列
StringBuffer类对象保存可修改的Unicode字符序列
StringBuilder类似,效率高,不考虑线程安全性
构造方法
修改方法:
append,insert,reverse,setCharart,setLength
class TestStringMethod
{
public static void main(String[] args)
{
String s = new String( "Hello World" );
System.out.println( s.length() );
System.out.println( s.indexOf('o') );
System.out.println( s.indexOf("He") );
System.out.println( s.startsWith("He") );
System.out.println( s.equals("Hello world") );
System.out.println( s.equalsIgnoreCase("Hello world") );
System.out.println( s.compareTo("Hello Java") );
System.out.println( s.charAt(1) );
System.out.println( s.substring(0,2) );
System.out.println( s.substring(2) );
System.out.println( s.concat("!!!") );
System.out.println( s.trim() );
System.out.println( s.toUpperCase() );
System.out.println( s.toLowerCase() );
System.out.println( s.replace('o', 'x' ) );
System.out.println( s ); //注意,s本身没有改变
}
}
字符串分割
java.util.StringToken类提供了对字符串进行分割的功能
构造
StringTokenizer(String str,String delim);
方法:
import java.util.*;
class TestStringTokenizer
{
public static void main(String[] args)
{
StringTokenizer st = new StringTokenizer("this is a test", " ");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
st = new StringTokenizer("253,197,546", ",");
double sum = 0;
while (st.hasMoreTokens()) {
sum += Double.parseDouble(st.nextToken());
}
System.out.println( sum );
}
}
calendar通过getTime()得到Date,Date通过getTime()得到long
Calendar
Date
SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”)
.format .parse
import java.util.Calendar;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Locale;
import static java.util.Calendar.*;
class CalendarDate
{
public static void main(String[] args) throws java.text.ParseException
{
Calendar calendar = Calendar.getInstance();
calendar.roll( MONTH, 1);
System.out.println( calendar.get(MONTH) + "月" + calendar.get( DAY_OF_MONTH ) + "日");
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
System.out.println( formatter.format(date ));
date = new SimpleDateFormat("yyyy-MM-dd").parse( "2013-4-23" );
calendar.setTime( date );
System.out.println( calendar.getDisplayName(DAY_OF_WEEK, LONG, Locale.CHINA) );
}
}
JDK8以后
import java.time.*;
import java.time.format.*;
class CalendarDate8{
public static void main(String[] args) throws java.text.ParseException
{
//使用默认时区时钟瞬时时间创建 Clock.systemDefaultZone() -->即相对于 ZoneId.systemDefault()默认时区
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
//自定义时区
LocalDateTime now2 = LocalDateTime.now(ZoneId.of("Europe/Paris"));
System.out.println(now2);//会以相应的时区显示日期
//构造一个对象
LocalDateTime d1 = LocalDateTime.of(2013, 12, 31, 23, 59, 59);
//解析String--->LocalDateTime
LocalDateTime d4 = LocalDateTime.parse("2013-12-31T23:59:59");
System.out.println(d4);
//使用DateTimeFormatter API 解析 和 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime d6 = LocalDateTime.parse("2013/12/31 23:59:59", formatter);
System.out.println(formatter.format(d6));
//时间获取的一部分
System.out.println(d6.getYear());
System.out.println(d6.getMonth()); //这不是整数,而是枚举
System.out.println(d6.getDayOfYear());
System.out.println(d6.getDayOfMonth());
System.out.println(d6.getDayOfWeek());
System.out.println(d6.getHour());
System.out.println(d6.getMinute());
System.out.println(d6.getSecond());
System.out.println(d6.getNano()); //纳秒
//时间增减
LocalDateTime d7 = d6.minusDays(1);
LocalDateTime d8 = d6.plusHours(1).plusMinutes(30);
System.out.println(d7);
System.out.println(d8);
}
}
collection接口:有两个子接口
List:记录元素保存顺序,且允许有重复元素
Set:不记录元素的保存顺序,且不允许有重复元素
Map接口,映射
键-值对的集合
List接口
import java.util.*;
public class TestArrayList{
public static void main(String[] args) {
ArrayList h = new ArrayList();
h.add("1st");
h.add("2nd");
h.add(new Integer(3));
h.add(new Double(4.0));
h.add("2nd"); // 重复元素, 加入
h.add(new Integer(3)); // 重复元素,加入
m1(h);
}
public static void m1(List s){
System.out.println(s);
}
}
//本应用程序输出结果如下[1st, 2nd, 3, 4.0, 2nd, 3]
使用增强for语句
for(Photo photo:album){
System.out.println(photo.toString());
}
import java.util.*;
class TestList {
public static void main(String[] args){
//List album = new ArrayList<>();
List<Photo> album = new LinkedList<>();
album.add( new Photo("one",new Date(), "classroom"));
album.add( new Photo("two",new Date(), "library"));
album.add( new Photo("three",new Date(), "gym"));
album.add( new Photo("three",new Date(), "dorm"));
Iterator<Photo> iterator = album.iterator();
while(iterator.hasNext()){
Photo photo = iterator.next();
System.out.println( photo.toString() );
}
for( Photo photo : album ){
System.out.println( photo );
}
}
}
class Photo {
String title;
Date date;
String memo;
Photo(String title, Date date, String memo){
this.title = title;
this.date = date;
this.memo = memo;
}
@Override
public String toString(){
return title + "(" + date + ")" + memo;
}
}
import java.util.*;
public class Stacks {
static String[] months = {
"January", "February", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December" };
public static void main(String[] args) {
Stack stk = new Stack();
for(int i = 0; i < months.length; i++)
stk.push(months[i] + " ");
System.out.println("stk = " + stk);
System.out.println("popping elements:");
while(!stk.empty())
System.out.println(stk.pop());
}
}
队列
import java.util.*;
class TestQueue
{
public static void main(String[] args)
{
Queue q = new Queue();
for( int i=0; i<5; i++ )
q.enqueue( ""+i );
while( ! q.isEmpty() )
System.out.println( q.dequeue() );
}
}
class Queue extends LinkedList
{
void enqueue( Object obj ){
addLast( obj );
}
Object dequeue(){
return removeFirst();
}
public boolean isEmpty(){
return super.isEmpty();
}
}
两个重要的实现 HashSet及TreeSet
Set中对象不重复:HashCode()不等
map是键值对的集合
import java.util.*;
class TestMap
{
public static void main( String[] args){
//Map map = new HashMap();
Map<String, String> map = new TreeMap<String, String>();
map.put("b", "Brazil");
map.put("r", "Russia");
map.put("i", "India");
map.put("c", "China");
map.put("k", "South Africa");
//map.put(new String("c"), "China2");
//map.put(new String("b"), "Brazil3");
System.out.println( map.get("c") );
for( String key : map.keySet() )
System.out.println( key +":" + map.get(key) );
for( String value : map.values() )
System.out.println( value );
for( Map.Entry<String,String> entry : map.entrySet() )
System.out.println( entry.getKey() +":" + entry.getValue() );
Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String,String> entry = (Map.Entry<String,String>)it.next();
System.out.println( entry.getKey() +":" + entry.getValue() );
}
}
}
Arrays.asList(10,7,6,5,9)//可以直接得到一个List对象
Arrays类提供sort()和binarySearch()
// Testing the sorting & searching in Arrays
import java.util.*;
public class TestArraysSort {
static Random r = new Random();
static String ssource =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz";
static char[] src = ssource.toCharArray();
// Create a random String
public static String randString(int length) {
char[] buf = new char[length];
int rnd;
for(int i = 0; i < length; i++) {
rnd = Math.abs(r.nextInt()) % src.length;
buf[i] = src[rnd];
}
return new String(buf);
}
// Create a random array of Strings:
public static
String[] randStrings(int length, int size) {
String[] s = new String[size];
for(int i = 0; i < size; i++)
s[i] = randString(length);
return s;
}
public static void print(byte[] b) {
for(int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
System.out.println();
}
public static void print(String[] s) {
for(int i = 0; i < s.length; i++)
System.out.print(s[i] + " ");
System.out.println();
}
public static void main(String[] args) {
byte[] b = new byte[15];
r.nextBytes(b); // Fill with random bytes
print(b);
Arrays.sort(b);
print(b);
int loc = Arrays.binarySearch(b, b[10]);
System.out.println("Location of " + b[10] +
" = " + loc);
// Test String sort & search:
String[] s = randStrings(4, 10);
print(s);
Arrays.sort(s);
print(s);
loc = Arrays.binarySearch(s, s[4]);
System.out.println("Location of " + s[4] +
" = " + loc);
}
}
对象是java.lang.Comparable
实现方法
public int compareTo(Object obj){
return this.price - ((Book)obj).price;
}
提供一个java.lang.Comparator
实现方法
public int compare(T 01,T o2)
import java.util.*;
class TestCollectionsSort
{
public static void main(String[] args)
{
List<Person> school = new ArrayList<Person>();
school.add( new Person("Li",23));
school.add( new Person("Wang",28));
school.add( new Person("Zhang",21));
school.add( new Person("Tang",19));
school.add( new Person("Chen",22));
school.add( new Person("Zhao",22));
System.out.println( school );
Collections.sort( school, new PersonComparator() );
System.out.println( school );
int index = Collections.binarySearch(
school, new Person("Li",23), new PersonComparator() );//给他一个比较器
if( index >=0 )
System.out.println( "Found:" + school.get( index ));
else
System.out.println( "Not Found!" );
}
}
class Person
{
String name;
int age;
public Person( String name, int age){
this.name=name;
this.age=age;
}
public String toString(){
return name+":"+age;
}
}
class PersonComparator implements Comparator
{
//实现一个自定义排序
public int compare( Object obj1, Object obj2 ){
Person p1 = (Person)obj1;
Person p2 = (Person)obj2;
if( p1.age > p2.age ) return 1;
else if(p1.age<p2.age) return -1;
return p1.name.compareTo( p2.name );
}
}
import java.util.*;
class TestCollectionsSortByLambda
{
public static void main(String[] args)
{
List<Person> school = new ArrayList<>();
school.add( new Person("Li",23));
school.add( new Person("Wang",28));
school.add( new Person("Zhang",21));
school.add( new Person("Tang",19));
school.add( new Person("Chen",22));
school.add( new Person("Zhao",22));
System.out.println( school );
Collections.sort( school, (p1,p2)->p1.age-p2.age );
System.out.println( school );
int index = Collections.binarySearch(
school, new Person("Li",23), (p1,p2)->p1.age-p2.age );
if( index >=0 )
System.out.println( "Found:" + school.get( index ));
else
System.out.println( "Not Found!" );
}
}
class Person
{
String name;
int age;
public Person( String name, int age){
this.name=name;
this.age=age;
}
public String toString(){
return name+":"+age;
}
}
使用泛型可以针对不同的类有相同的处理方法
Vector <String> v = new Vector <String> ();
v.addElement("one");
String s = v.elementAt(0);
import java.util.*;
class GenericTreeClass {
public static void main(String[] args){
TNode<String> t = new TNode<>("Roo");
t.add("Left"); t.add("Middle"); t.add("Right");
t.getChild(0).add("aaa");
t.getChild(0).add("bbb");
t.traverse();
}
}
class TNode<T>
{
private T value;
private ArrayList<TNode<T>> children = new ArrayList<>();
TNode(T v) {
this.value = v; }
public T getValue() {
return this.value; }
public void add(T v) {
TNode<T> child = new TNode<>(v);
this.children.add(child);
}
public TNode<T> getChild(int i) {
if ((i < 0) || (i > this.children.size())) return null;
return (TNode<T>)this.children.get(i);
}
public void traverse() {
System.out.println(this.value);
for (TNode child : this.children)
child.traverse();
}
import java.util.*;
class GenericMethod {
public static void main(String[] args){
Date date = BeanUtil.<Date>getInstance("java.util.Date");
System.out.println(date);
}
}
class BeanUtil{
public static <T> T getInstance( String clzName ){
try
{
Class c = Class.forName(clzName);
return (T) c.newInstance();
}
catch (ClassNotFoundException ex){
}
catch (InstantiationException ex){
}
catch (IllegalAccessException ex){
}
return null;
}
}
对类型限定
进程:一个程序的执行
线程:程序中单个顺序的流控制
一个程序中可以含有多个线程
通过继承Thread类创建线程
class MyThread extends Thread{
public void run(){
for(int i=0;i<100;i++){
System.out.print(" "+i);
}
}
}
通过向Thread()构造方法传递Runnable对象来创建线程
class MyTask implements Runnable{
public void run(){
}
}
Thread thread = new Thread(mytask);
thread.start();
使用匿名类
new Thread(){
public void run(){
for(int i=0;i<10;i++){
System.out.print(i);
}
}
}
使用Lambda表达式
new Thread( ()-> {...}).start();
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
public static void main(String args[]) {
Counter c1 = new Counter(1);
Thread t1 = new Thread(c1);
Thread t2 = new Thread(c1);
Thread t3 = new Thread(c1);
Counter c2 = new Counter(2);
Thread t4 = new Thread(c2);
Thread t5 = new Thread(c2);
Thread t6 = new Thread(c2);
TimeDisplay timer = new TimeDisplay();
Thread t7 = new Thread(timer);
t1.start();
t2.start();
t4.start();
t5.start();
}
}
class Counter implements Runnable {
int id;
Counter(int id) {
this.id = id;
}
public void run() {
int i = 0;
while (i++ <= 10) {
System.out.println("ID: " + id + " No. " + i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}
}
class TimeDisplay implements Runnable {
public void run() {
int i = 0;
while (i++ <= 3) {
System.out.println(new SimpleDateFormat().format(new Date()));
try {
Thread.sleep(40);
} catch (InterruptedException e) {
}
}
}
}
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.*;
public class Test extends JApplet
{
MovingShape [] shapes;
public void init()
{
setLayout(null);
setSize(426,266);
shapes = new MovingShape[ 10 ];
for( int i=0; i<shapes.length; i++ ){
shapes[i] = new MovingShape(this);
shapes[i].start();
}
}
public void destroy()
{
for( int i=0; i<shapes.length; i++ )
shapes[i].stopped =true;
super.destroy();
}
public static void main(String [] args) //加入main,使之能当Application应用
{
Frame f = new Frame();
f.setSize(450,300 );
Test p = new Test();
f.add ( p );
f.setVisible( true );
p.init();
p.start();
f.addWindowListener( new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0); }
});
}
}
class MovingShape extends Thread
{
private int size=100;
private int speed=10;
private Color color;
private int type;
private int x,y,w,h,dx,dy;
protected java.awt.Component app;
public boolean stopped;
MovingShape( java.awt.Component app )
{
this.app = app;
x = (int)(Math.random() * app.getSize().width);
y = (int)(Math.random() * app.getSize().height);
w = (int)(Math.random() * size );
h = (int)(Math.random() * size );
dx = (int)(Math.random() * speed );
dy = (int)(Math.random() * speed );
color = new Color (
(int)(Math.random()*128+128),
(int)(Math.random()*128+128),
(int)(Math.random()*128+128) );
type = (int)(Math.random() * 3 );
}
public void run()
{
while( true ){
if( stopped ) break;
//draw();
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
draw();
}
} );
try{
Thread.sleep(130); } catch( InterruptedException e ){
}
}
}
void draw(){
x += dx;
y += dy;
if( x<0 || x+w>app.getSize().width ) dx = -dx;
if( y<0 || y+h>app.getSize().height) dy = -dy;
Graphics g = app.getGraphics();
switch( type ){
case 0:
g.setColor(color);
g.fillRect( x,y,w,h );
g.setColor( Color.black );
g.drawRect( x,y,w,h );
break;
case 1:
g.setColor(color);
g.fillOval( x,y,w,h );
g.setColor( Color.black );
g.drawOval( x,y,w,h );
break;
case 2:
g.setColor(color);
g.fillRoundRect( x,y,w,h,w/5,h/5);
g.setColor( Color.black );
g.drawRoundRect( x,y,w,h,w/5,h/5 );
break;
}
}
}
启动
start()
结束
设定一个标记变量,以结束相应的循环
暂时阻止线程执行
try{
Thread.sleep(1000);}catch(InterruptedException e){
}
设定线程优先级
setPriority(int priority)方法
MIN_PRIORITY, MAX_PRIORITY, NORM_PRIORITY
使用setDaemon(true);
例如垃圾回收线程是后台线程
import java.util.*;
public class TestThreadDaemon {
public static void main(String args[]) {
Thread t = new MyThread();
t.setDaemon(true);
t.start();
System.out.println( "Main------" + new Date());
try{
Thread.sleep(500); } catch(InterruptedException ex){
}
System.out.println("Main End");
}
}
class MyThread extends Thread {
public void run() {
for(int i=0; i<10; i++ ){
System.out.println( i + "------" + new Date());
try{
Thread.sleep(100); } catch(InterruptedException ex){
}
}
}
}
class TestThreadCount
{
public static int cnt=0;
public static void main(String[] args)
{
final int NUM=50000;
Thread [] threads = new Thread[NUM];
for(int i=0; i<NUM; i++){
threads[i] = new Thread(){
public void run(){
cnt++;
}
};
}
for(int i=0; i<NUM; i++) threads[i].start();
try{
Thread.sleep(3000); } catch(InterruptedException ex){
}
System.out.printf("%d %b\n", cnt, cnt==NUM);
}
}
保证共享数据操作的完整性
每个对象都对应于一个monitor监视器,他上面一个成为互斥锁的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象
关键字synchronized用来与对象的互斥锁联系
synchronized用法:
class SyncCounter2
{
public static void main(String[] args){
Num num = new Num();
Thread counter1 = new Counter(num);
Thread counter2 = new Counter(num);
for( int i=0; i<10; i++ ){
num.testEquals();
try{
Thread.sleep(100);
}catch(InterruptedException e){
}
}
}
}
class Num
{
private int x=0;
private int y=0;
synchronized void increase(){
x++;
y++;
}
synchronized boolean testEquals(){
boolean ok = (x==y);
System.out.println( x + "," + y +" :" + ok);
return ok;
}
}
class Counter extends Thread
{
private Num num;
Counter( Num num ){
this.num = num;
this.setDaemon(true);
this.setPriority(MIN_PRIORITY);
this.start();
}
public void run(){
while(true){
num.increase();
}
}
}
使用wait()方法可以释放对象锁
使用notify()或notifyAll()可以让等待的一个或所有线程进入就绪状态
class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i <10; i++) {
cubbyhole.put(i);
//System.out.println("Producer #" + this.number + " put: " + i);
//try {
// sleep((int)(Math.random() * 100));
//} catch (InterruptedException e) {
//}
}
}
}
class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i <10; i++) {
value = cubbyhole.get();
//System.out.println("Consumer #" + this.number + " got: " + value);
}
}
}
class CubbyHole1
{
private int seq;
public synchronized int get() {
return seq;
}
public synchronized void put(int value) {
seq = value;
}
}
class CubbyHole2
{
private int seq;
private boolean available = false;
public synchronized int get() {
while (available == false) ; //dead locked !!!
return seq;
}
public synchronized void put(int value) {
while (available == true) ;
seq = value;
available = true;
}
}
class CubbyHole3 {
private int seq;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait(); // waits for notify() call from Producer
} catch (InterruptedException e) {
}
}
available = false;
notify();
return seq;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait(); // waits for notify() call from consumer
} catch (InterruptedException e) {
}
}
seq = value;
available = true;
notify();
}
}
class CubbyHole {
private int data[] = new int[3];
private int index = 0;
public synchronized int get() {
while (index <= 0) {
try {
wait(); // waits for notify() call from Producer
} catch (InterruptedException e) {
}
}
index --;
int value = data[index];
System.out.println("Consumer " + " got: " + data[index]);
notify();
return value;
}
public synchronized void put(int value) {
while (index >= data.length) {
try {
wait(); // waits for notify() call from consumer
} catch (InterruptedException e) {
}
}
System.out.println("Producer " + " put: " + value);
data[index] = value;
index ++;
notify();
}
}
class ProducerConsumerStack {
public static void main(String args[]) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
p1.start();
c1.start();
}
}
也有可能造成死锁互相等待的情况
class DeadLockDemo{
class Worker
{
int id;
public Worker(int id){
this.id=id; }
synchronized void doTaskWithCooperator(Worker other){
try{
Thread.sleep(500); } catch(Exception e){
}
synchronized(other){
System.out.println("doing" + id);
}
}
}
void test(){
Worker w1 = new Worker(1);
Worker w2 = new Worker(2);
Thread td1 = new Thread(){
public void run(){
w1.doTaskWithCooperator(w2);
}
};
Thread td2 = new Thread(){
public void run(){
w2.doTaskWithCooperator(w1);
}
};
td1.start();
td2.start();
}
public static void main(String[] args) {
new DeadLockDemo().test();
}
}
java.util.concurrent包
Java.util.concurrent.atomic
AtomicInteger类
getAndIncrement()方法
import java.util.concurrent.atomic.AtomicInteger ;
class AtomicIntegerDemo
{
public static AtomicInteger cnt = new AtomicInteger(0);
public static void main(String[] args)
{
final int NUM=10000;
Thread [] threads = new Thread[NUM];
for(int i=0; i<NUM; i++){
threads[i] = new Thread(){
public void run(){
cnt.getAndIncrement();
}
};
}
for(int i=0; i<NUM; i++) threads[i].start();
try{
Thread.sleep(3000); } catch(InterruptedException ex){
}
System.out.printf("%d %b\n", cnt.get(), cnt.get()==NUM);
}
}
线程池相关类
ExecutorService接口,ThreadPoolExecutor类
Executors工具类
ExecutorService pool = Executors.newCachedThreadPool();
使用其execute( Runnable r)方法
import java.util.concurrent.*;
class ThreadPoolDemo
{
public static void main(String[] args)
{
ExecutorService pool = Executors.newCachedThreadPool();
MyTask t1 = new MyTask(5);
MyTask t2 = new MyTask(7);
MyTask t3 = new MyTask(8);
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.shutdown();
}
}
class MyTask implements Runnable
{
int n=10;
public MyTask(int n){
this.n=n;}
public void run(){
for(int i=0;i<n; i++)System.out.print(i);
}
}
JComponent是非顶层容器,都是容器,都有add子组件
import javax.swing.*;
import java.awt.*;
public class TestJFrame extends JFrame
{
private JLabel lbl;
public TestJFrame()
{
super("Test JFrame");
lbl = new JLabel("Hello Swing");
//add(lbl);
getContentPane().add(lbl);
setSize(300, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
new TestJFrame().setVisible(true);
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class JButtonDemo extends JFrame {
JButton b1 = new JButton("JButton 1");
JButton b2 = new JButton("JButton 2");
JTextField t = new JTextField(20);
public JButtonDemo() {
b1.setToolTipText("Press Button will show msg");
b1.setIcon( new ImageIcon( "cupHJbutton.gif") );
getContentPane().setLayout( new FlowLayout() );
getContentPane().add(b1);
getContentPane().add(b2);
getContentPane().add(t);
setSize(400,300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e){
String name =
((JButton)e.getSource()).getText();
t.setText(name + " Pressed");
}
};
b1.addActionListener(al);
b2.addActionListener(al);
}
public static void main(String args[]) {
new JButtonDemo().setVisible(true);
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestActionEvent {
public static void main(String args[]) {
JFrame f = new JFrame("Test");
JButton btn = new JButton("Press Me!");
f.add(btn);
ActionListener al = new MyListener();
btn.addActionListener(al);
f.setSize(300, 120);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
class MyListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("a button has been pressed");
}
}
事件监听器是一些事件的接口
接口中含有相关的方法:
MouseMotionListener是对鼠标移动事件的处理的接口,它含有两个重要的方法:
void mouseDragged(MouseEvent e);//处理鼠标拖动的方法
void mouseMoved(MoudeEvent e);//处理鼠标移动方法
事件类中包含有事件相关的信息:
简化实现Listener
add xxxx Listener