在ubuntu 14.04上java开发环境。
下载 jdk-7u75-linux-x64.tar.gz
使用tar xvf jdk-7u75-linux-x64.tar.gz 解压
在/usr/lib/ 下创建jvm目录,将解压过的java文件夹移动进来
在 /etc/profile中添加
#set java environment export JAVA_HOME=/usr/lib/jvm/你的jdk目录名字 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH
运行下列两行语句即可
sudo update-alternatives --install /usr/bin/java java /usr/lib/jdk1.7.0_06/bin/java 300 sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jdk1.7.0_06/bin/javac 300
第二种
sudo apt-get install openjdk-7-jdk
Java基本的数据类型:bootlean、byte、char、short、int、long、float、double
第一个例子:
/* * filename hello.java */ public class hello { public static void main( String args[] ) { System.out.println("Hello world"); } }
注:class的类名要和文件名一致。
javac hello.java //编译 会自动生成hello.class 文件
java hello // 执行
在申请一块内存后,如果想释放,直接给指针赋空即可。java的垃圾回收机制会自动释放内存。
char str[] = new char[100];
str = null; //释放内存
如果想在类的定义的时候自动执行一段代码,不一定要写在构造函数中,也可以写在构造块中。
java中,在类中直接添加一个大括号,里面添加相应的代码,即为构造块。构造块比构造函数先执行。
还有一种就是静态代码块。
静态代码块与构造块不同的是静态代码块只执行一次。并且要在大括号前加static。
在继承(extends)中,默认调用父类无参的构造函数(super())。
如果需要调用有参数的,需要使用 super( 参数1,参数2,..... )
继承的限制:
1. 父类的私有成员,子类无法直接访问。
2.子类去除父类的成员。
3.子类不能修改父类的权限。
抽象类:
在父类中可以声明抽象方法而不定义。但是子类如果继承父类,则必须实现抽象方法。
抽象类不能有实例化对象,只能用来继承。
在声明抽象方法时,需要用abstract来修饰
接口(implements):
一个子类只能继承一个父类,但是一个子类可以可以多个接口。
数据类型转换:
整数默认是int,小数默认是double.
1. Java基础
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/1.%20Java%E5%9F%BA%E7%A1%80.jpg)
第一个Java程序
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E7%AC%AC%E4%B8%80%E4%B8%AAJava%E7%A8%8B%E5%BA%8F.jpg)
代码
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E4%BB%A3%E7%A0%81.jpg)
Hello.java
public class Hello {
public static void main (String args[]) {
System.out.println("Hello, world!");
}
}
编译
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E7%BC%96%E8%AF%91.jpg)
javac Hello.java
运行
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E8%BF%90%E8%A1%8C.jpg)
java Hello
数据类型
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.jpg)
基本数据类型
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.jpg)
引用数据类型
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%BC%95%E7%94%A8%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.jpg)
使用new来分配,不需要自己释放,把变量设为null即可
int p[]=new int [10];
p = null;
数组
int a[]=null;
a = new int[10];
int b[]=new int[10];
int c[]={1,2,3,4,5};
类
接口
null
数据类型转换
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.jpg)
自动转换
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E8%87%AA%E5%8A%A8%E8%BD%AC%E6%8D%A2.jpg)
数据不丢失的前提下可以自动转换
int a=30;
long b = a; // 自动转换,因为long的表示范围比int大
float c = 3.1
int d = (int)c; // 必须使用强制转换
注意:整数默认是int,有小数时默认是double
强制转换
例子
byte b= 1;
short s= 3;
编译器会判断该值有无超过该变量的表示范围,如果超过就报错。
short s = 1;
s = s + 1; // 出错,因为对于byte,short的运算,为了保证精度,会自动转换为int类型
s = (short)(s + 1);
short s2 = 1;
s = s + s2; // 出错,理由同上
运算符、表达式、语句
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E8%BF%90%E7%AE%97%E7%AC%A6%E3%80%81%E8%A1%A8%E8%BE%BE%E5%BC%8F%E3%80%81%E8%AF%AD%E5%8F%A5.jpg)
跟C语言完全一样
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E8%B7%9FC%E8%AF%AD%E8%A8%80%E5%AE%8C%E5%85%A8%E4%B8%80%E6%A0%B7.jpg)
if, if...else, if...else if...else, switch
while, do...while, for; break, continue
方法
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%96%B9%E6%B3%95.jpg)
格式
public static 返回值类型 方法名称 (类型 参数1, 类型 参数2, ...) {
程序语句;
[return 表达式];
}
示例:
public static int add(int x, int y) {
int sum;
sum = x + y;
return sum;
}
重载
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E9%87%8D%E8%BD%BD.jpg)
方法名相同
参数类型或个数不同
返回值可以相同也可以不同
参数
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%8F%82%E6%95%B0.jpg)
基本数据作为参数
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E4%BD%9C%E4%B8%BA%E5%8F%82%E6%95%B0.jpg)
方法内部对参数的修改不影响调用者
引用数据作为参数
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%BC%95%E7%94%A8%E6%95%B0%E6%8D%AE%E4%BD%9C%E4%B8%BA%E5%8F%82%E6%95%B0.jpg)
方法内部修改了堆,结果会保留下来
2. 面向对象程序设计
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/2.%20%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1.jpg)
类的引入
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E7%B1%BB%E7%9A%84%E5%BC%95%E5%85%A5.jpg)
C语言中的结构体(struct)
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/C%E8%AF%AD%E8%A8%80%E4%B8%AD%E7%9A%84%E7%BB%93%E6%9E%84%E4%BD%93(struct).jpg)
struct Person {
char name[100];
int age;
int money;
char *(*getName)(struct Person per);
int (*getMoney)(struct Person per);
};
char *getName(struct Person per)
{
return per.name;
}
int getMoney(struct Person per)
{
return per.money;
}
struct Person per;
struct Person *p = malloc(sizeof(struct Person));
per.getName = getName;
per.getMoney = getMoney;
p->getName = getName;
p->getMoney = getMoney;
int i = per.age;
char *str = per.getName();
类型定义
创建结构体
使用
Java中的类(class)
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/Java%E4%B8%AD%E7%9A%84%E7%B1%BB(class).jpg)
class 类名称 {
数据类型 属性;
...
public 返回值类型 方法名称 (参数1, 参数2, ...) {
程序语句;
[return 表达式;]
}
}
class Person {
String name;
int age;
int money;
public String getName( );
public int getMoney( );
}
Person per = null;
per = new Person( );
int i = per.age;
int m = per.getMoney( );
class定义
创建对象
访问属性和方法
构造方法
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95.jpg)
class Person {
String name;
int age;
int money;
public String getName( );
public int getMoney( );
// 构造方法
访问权限 类名称 (类型1 参数1, 类型2 参数2, ...) {
程序语句;
..... // 构造方法没有返回值
}
}
如果没实现构造方法,编译器自动加上一个无参数的空构造方法
this关键字
表示当前对象, 当前类
static关键字
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/static%E5%85%B3%E9%94%AE%E5%AD%97.jpg)
类属性
类方法
代码块
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E4%BB%A3%E7%A0%81%E5%9D%97.jpg)
普通代码块
方法的{}就是普通代码块
构造代码块
class Person {
{
// 构造块
// 每实例化一个对象前,都执行;先于构造方法执行
}
}
静态代码块
class Person {
static {
// 静态块
// 实例化第一个对象前,执行;只执行一次
}
}
封装性
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%B0%81%E8%A3%85%E6%80%A7.jpg)
权限
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%9D%83%E9%99%90.jpg)
private
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/private.jpg)
本类可访问
default
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/default.jpg)
本包可访问
protected
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/protected.jpg)
本包、其他包的子类可访问
public
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/public.jpg)
所有
使用方法来访问属性
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%E6%9D%A5%E8%AE%BF%E9%97%AE%E5%B1%9E%E6%80%A7.jpg)
setter
getter
继承性
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E7%BB%A7%E6%89%BF%E6%80%A7.jpg)
引入
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%BC%95%E5%85%A5.jpg)
格式
class 父类{ }
class 子类 extends 父类 { }
构造方法
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95%202.jpg)
如果一个类没有实现构造方法,java编译器会给它定义一个空的构造方法
实例化子类对象时,先调用父类的构造方法,再调用子类的构造方法
super关键字
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/super%E5%85%B3%E9%94%AE%E5%AD%97.jpg)
子类的构造方法里会默认调用super()
可以在子类构造方法中首行自己调用super(),可加参数
super表示父类,可以用super.xxxx调用父类方法
子类继承父类的属性和方法,也可以覆写
final关键字
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/final%E5%85%B3%E9%94%AE%E5%AD%97.jpg)
final类不能有子类
final方法不能被覆写
final变量变成常量,不能被修改
继承的限制
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E7%BB%A7%E6%89%BF%E7%9A%84%E9%99%90%E5%88%B6.jpg)
看不到父亲的私房钱:私有属性不能被子类访问
看不到父亲的绝招:私有方法不能被子类访问
不能把祖传的招式私吞了:子类覆写的方法不能缩小权限
抽象类
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%8A%BD%E8%B1%A1%E7%B1%BB.jpg)
abstract class 类名 {
属性;
普通方法 { }
// 抽象方法
访问权限 abstract 返回值类型 方法名 (参数) ; /* 只需要声明,不需要实现 */
}
作用:规定子类必须实现的方法,起“模板”作用
不能实例化对象
子类必须覆写全部抽象方法
接口
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%8E%A5%E5%8F%A3.jpg)
// 接口由全局常量、公共的抽象方法组成
interface 接口名称 {
全局常量;
抽象方法;
}
interface A {
public static final i = 10;
public abstract int getNumber( );
}
interface B {
public static final String name = "www.100ask.net";
public abstract int getName( );
}
class C implements A,B {
//覆写A中方法
public int getNumber () { return i; }
//覆写B中方法
public int getName () { return name; }
}
作用:跟抽象类相似,起“模板”作用;子类可以继承多个接口,突破“单继承”的限制
子类必须覆写全部抽象方法
多态性
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%A4%9A%E6%80%81%E6%80%A7.jpg)
方法的重载与覆写
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%96%B9%E6%B3%95%E7%9A%84%E9%87%8D%E8%BD%BD%E4%B8%8E%E8%A6%86%E5%86%99.jpg)
重载overload: 定义多个同名方法,其参数类型、个数不同
覆写override:子类里实现跟父类同样的方法
对象的多态性
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%A4%9A%E6%80%81%E6%80%A7.jpg)
向上转换
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%90%91%E4%B8%8A%E8%BD%AC%E6%8D%A2.jpg)
父类 父类对象 = 子类实例;
Son son = new Son(); Father f = son;
f.fun(...)只能调用被子类覆写的方法,不能调用只在子类中定义的方法
向下转换
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%90%91%E4%B8%8B%E8%BD%AC%E6%8D%A2.jpg)
子类 子类对象 = (子类)父类实例;
Father f = new Son(); Son son = (Son)f;
在进行对象的向下转换前,必须首先发生对象的向上转换
instanceof: 用来判断一个对象是不是某个类的实例
异常
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%BC%82%E5%B8%B8.jpg)
异常
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%BC%82%E5%B8%B8%202.jpg)
JAVA异常类
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/JAVA%E5%BC%82%E5%B8%B8%E7%B1%BB.jpg)
分为Error, Exception两类
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%88%86%E4%B8%BAError,%20Exception%E4%B8%A4%E7%B1%BB.jpg)
Error
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/Error.jpg)
JAVA虚拟机本身的问题,跟程序无关,程序不需要处理
Exception
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/Exception.jpg)
程序本身可以处理的异常
还可以分为
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E8%BF%98%E5%8F%AF%E4%BB%A5%E5%88%86%E4%B8%BA.jpg)
不可查的异常(unchecked exceptions)
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E4%B8%8D%E5%8F%AF%E6%9F%A5%E7%9A%84%E5%BC%82%E5%B8%B8(unchecked%20exceptions).jpg)
RuntimeException及其子类
可查的异常(checked exceptions)
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%8F%AF%E6%9F%A5%E7%9A%84%E5%BC%82%E5%B8%B8(checked%20exceptions).jpg)
其他异常
还可以分为
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E8%BF%98%E5%8F%AF%E4%BB%A5%E5%88%86%E4%B8%BA%202.jpg)
运行时异常
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E8%BF%90%E8%A1%8C%E6%97%B6%E5%BC%82%E5%B8%B8.jpg)
RuntimeException及其子类
非运行时异常(编译异常)
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E9%9D%9E%E8%BF%90%E8%A1%8C%E6%97%B6%E5%BC%82%E5%B8%B8(%E7%BC%96%E8%AF%91%E5%BC%82%E5%B8%B8).jpg)
其他异常
处理原则
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%A4%84%E7%90%86%E5%8E%9F%E5%88%99.jpg)
对于可查异常必须捕捉、或者声明抛出; 允许忽略不可查的RuntimeException和Error
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%AF%B9%E4%BA%8E%E5%8F%AF%E6%9F%A5%E5%BC%82%E5%B8%B8%E5%BF%85%E9%A1%BB%E6%8D%95%E6%8D%89%E3%80%81%E6%88%96%E8%80%85%E5%A3%B0%E6%98%8E%E6%8A%9B%E5%87%BA;%20%20%E5%85%81%E8%AE%B8%E5%BF%BD%E7%95%A5%E4%B8%8D%E5%8F%AF%E6%9F%A5%E7%9A%84RuntimeException%E5%92%8CError.jpg)
“运行时异常”都是“不可查异常”
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E2%80%9C%E8%BF%90%E8%A1%8C%E6%97%B6%E5%BC%82%E5%B8%B8%E2%80%9D%E9%83%BD%E6%98%AF%E2%80%9C%E4%B8%8D%E5%8F%AF%E6%9F%A5%E5%BC%82%E5%B8%B8%E2%80%9D.jpg)
程序中可以捕获处理它,也可以不处理
其他异常在程序中必须处理,否则连编译都过不了
处理方法
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%A4%84%E7%90%86%E6%96%B9%E6%B3%95.jpg)
try...catch...finally
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/try...catch...finally.jpg)
try {
// 程序语句,可能发生异常
} catch (异常类型1 e) {
// 处理语句
} catch (异常类型2 e) {
// 处理语句
} catch (异常类型3 e) {
......
}
[ finally {
//一定会运行到的代码
} ]
try或catch块中有return或throw语句, 会先执行finally块,再返回来执行return或throw语句
或者再次向上throws
throws
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/throws.jpg)
写在方法的声明位置,表示如果发生异常,扔给调用者处理
public 返回值 方法名(参数列表……) throws 异常类 { }
public int div (int m, int n) throws Exception {
......
}
对于“不可查异常”, 系统也会抛出它,写不写throws效果一样
对于“可查异常”,必须处理;处理方法见上
throw
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/throw.jpg)
人为抛出一个异常
throw 异常类的实例化对象;
throw new Exception("My Error");
throw“不可查异常”时,可以不处理它
throw“可查异常”时,必须处理; 处理方法见上
assert
assert boolean表达式 ;
assert boolean表达式 : 详细信息 ;
表达式为true时,无错误;
表达式为false时,打印“详细信息”
assert x == 0;
assert x == 0 : "X is not zero";
包及访问权限
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%8C%85%E5%8F%8A%E8%AE%BF%E9%97%AE%E6%9D%83%E9%99%90.jpg)
包
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%8C%85.jpg)
package
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/package.jpg)
包实际上是一个文件夹(可以含有多级子目录)
格式:package 包名称.子包名称; 例子:package a.b.c.d;
编译命令:javac -d <dir> <file.java> (表示在<dir>目录下生成包)
执行方法:java 包名称.子包名称.类名称
作用:解决类的同名冲突问题
import
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/import.jpg)
使用不同包的类时需要import
格式: import 包名称.子包名称.类名称; // 手工导入某个类 import 包名称.子包名称.* ; // 由JVM自动加载所需要的类
jar
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/jar.jpg)
生成:jar -cvf <file.jar> <dir>
查看:jar -tvf <file.jar>
解压:tar -xvf <file.jar>
CLASSPATH
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/CLASSPATH.jpg)
指定编译时查找源码的目录
指定运行时查找的“.class文件的目录”或“jar文件”
设置方法: export CLASSPATH=<dir1>:<dir2>:....:<file1.jar>:<file2.jar>:...
权限
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%9D%83%E9%99%90%202.jpg)
类
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E7%B1%BB.jpg)
public class可以被外包访问
class只能在本包中访问
类成员
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E7%B1%BB%E6%88%90%E5%91%98.jpg)
private
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/private%202.jpg)
本类可访问
default
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/default%202.jpg)
本包可访问
protected
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/protected%202.jpg)
本包、其他包的子类可访问
public
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/public%202.jpg)
所有
内部类
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%86%85%E9%83%A8%E7%B1%BB.jpg)
一般内部类
在内的内部定义一个类
class Outer {
class Inner {
}
}
Inner被称为内部类。
好处:内部类可以直接访问外部类的私有属性
示例:
Outer o = new Outer( );
Outer.Inner i = o.new Inner( );
静态内部类
class Outer {
static class Inner {
}
}
用static声明的内部类就变成了外部类;
它可以访问外部类的static属性
使用示例:
Outer.Inner a = new Outer.Inner( );
匿名内部类
interface A {
public void printInfo( );
}
class B implements A {
public void printInfo( ) {
System.out.println("Hello, world!");
}
}
public class Anony {
public static void testFunc(A a) {
a.printInfo( );
}
public static void main(String args[]) {
testFunc(new B());
testFunc(new A( ) {
public void printInfo() {
System.out.println("Hello, world!");
}
});
}
}
3. JNI
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/3.%20JNI.jpg)
JAVA调用C
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/JAVA%E8%B0%83%E7%94%A8C.jpg)
Java访问C库的方法
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/Java%E8%AE%BF%E9%97%AEC%E5%BA%93%E7%9A%84%E6%96%B9%E6%B3%95.jpg)
1. 加载C库
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/1.%20%E5%8A%A0%E8%BD%BDC%E5%BA%93.jpg)
System.loadLibrary
2. 建立Java函数名到C库函数名的映射关系
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/2.%20%E5%BB%BA%E7%AB%8BJava%E5%87%BD%E6%95%B0%E5%90%8D%E5%88%B0C%E5%BA%93%E5%87%BD%E6%95%B0%E5%90%8D%E7%9A%84%E6%98%A0%E5%B0%84%E5%85%B3%E7%B3%BB.jpg)
隐式建立
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E9%9A%90%E5%BC%8F%E5%BB%BA%E7%AB%8B.jpg)
类a.b.c.d.JNIDemo要调用hello函数
C语言中要实现Java_a_b_c_d_JNIDemo_hello
可以用工具生成头文件
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%8F%AF%E4%BB%A5%E7%94%A8%E5%B7%A5%E5%85%B7%E7%94%9F%E6%88%90%E5%A4%B4%E6%96%87%E4%BB%B6.jpg)
javac -d . JNIDemo.java
javah -jni a.b.c.d.JNIDemo
显示建立
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%98%BE%E7%A4%BA%E5%BB%BA%E7%AB%8B.jpg)
JNI_OnLoad
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/JNI_OnLoad.jpg)
加载C库时就会调用这个函数
RegisterNatives
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/RegisterNatives.jpg)
定义一个映射数组JNINativeMethod[]
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AA%E6%98%A0%E5%B0%84%E6%95%B0%E7%BB%84JNINativeMethod[].jpg)
typedef struct {
char *name; /* Java里调用的函数名 */
char *signature; /* JNI字段描述符, 用来表示Java里调用的函数的参数和返回值类型 */
void *fnPtr; /* C语言实现的本地函数 */
} JNINativeMethod;
static const JNINativeMethod methods[] = {
{"hello", "(Ljava/lang/String;)Ljava/lang/String", (void *)native_hello},
};
每个数组项含3个成员
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%AF%8F%E4%B8%AA%E6%95%B0%E7%BB%84%E9%A1%B9%E5%90%AB3%E4%B8%AA%E6%88%90%E5%91%98.jpg)
Java里调用的函数名
JNI字段描述符
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/JNI%E5%AD%97%E6%AE%B5%E6%8F%8F%E8%BF%B0%E7%AC%A6.jpg)
用"["表示数组,比如"int []"表示为"[I"
对于类,要用全称"L包.子包.类名;"(前面有"L",后面有";"), 比如"Ljava/lang/String;"
除String类外,其他的类都用Object表示,即"Ljava/lang/Object;"
C语言实现的本地函数
注册这个数组
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%B3%A8%E5%86%8C%E8%BF%99%E4%B8%AA%E6%95%B0%E7%BB%84.jpg)
(*env)->RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
注意:C函数比Java里的声明多2个参数: (JNIEnv *env, jclass cls)
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%B3%A8%E6%84%8F%EF%BC%9AC%E5%87%BD%E6%95%B0%E6%AF%94Java%E9%87%8C%E7%9A%84%E5%A3%B0%E6%98%8E%E5%A4%9A2%E4%B8%AA%E5%8F%82%E6%95%B0%20%20(JNIEnv%20%20env,%20jclass%20cls).jpg)
env提供一些辅助函数,后面有例子
cls是对Java类或实例的引用
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/cls%E6%98%AF%E5%AF%B9Java%E7%B1%BB%E6%88%96%E5%AE%9E%E4%BE%8B%E7%9A%84%E5%BC%95%E7%94%A8.jpg)
如果是static方法,则cls是对Java类的引用
否则,cls是对类的实例化对象的引用
3. 在Java程序里调用函数
简单例子
Java和C库传递数据
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/Java%E5%92%8CC%E5%BA%93%E4%BC%A0%E9%80%92%E6%95%B0%E6%8D%AE.jpg)
传递基本类型数据
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E4%BC%A0%E9%80%92%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B%E6%95%B0%E6%8D%AE.jpg)
直接使用、直接返回
传递字符串 (jni.pdf P39)
以下函数从Java中获得一个字符串,
再返回一个字符串给Java:
JNIEXPORT jstring JNICALL
Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
{
char buf[128];
const jbyte *str;
str = (*env)->GetStringUTFChars(env, prompt, NULL);
if (str == NULL) {
return NULL; /* OutOfMemoryError already thrown */
}
printf("%s", str);
(*env)->ReleaseStringUTFChars(env, prompt, str);
/* We assume here that the user does not type more than
* 127 characters */
scanf("%s", buf);
return (*env)->NewStringUTF(env, buf);
}
传递数组 (jni.pdf P48
以下函数从Java中获得一个int数组,
再求和返回一个整数给Java:
JNIEXPORT jint JNICALL
Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
{
jint *carr;
jint i, sum = 0;
carr = (*env)->GetIntArrayElements(env, arr, NULL);
if (carr == NULL) {
return 0; /* exception occurred */
}
for (i=0; i< (*env)->GetArrayLength(env, arr); i++) {
sum += carr[i];
}
(*env)->ReleaseIntArrayElements(env, arr, carr, 0);
return sum;
}
C调用JAVA (jni.pdf P97)
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/C%E8%B0%83%E7%94%A8JAVA%20(jni.pdf%20P97).jpg)
步骤
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E6%AD%A5%E9%AA%A4.jpg)
1. 创建虚拟机
JavaVM* jvm;
JNIEnv* env;
jint create_vm(JavaVM** jvm, JNIEnv** env)
{
JavaVMInitArgs args;
JavaVMOption options[1];
args.version = JNI_VERSION_1_6;
args.nOptions = 1;
options[0].optionString = "-Djava.class.path=.";
args.options = options;
args.ignoreUnrecognized = JNI_FALSE;
return JNI_CreateJavaVM(jvm, (void **)env, &args);
}
2. 获得class
jclass cls = (*env)->FindClass(env, "Hello");
3. 实例化对象
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/3.%20%E5%AE%9E%E4%BE%8B%E5%8C%96%E5%AF%B9%E8%B1%A1.jpg)
对于静态方法,不需要实例化对象
也是通过调用JAVA方法实现
jmethodID mid = (*env)->GetMethodID(env, cls, "<init>", "()V"); // 获得构造方法
jobject obj = (*env)->NewObject(env, cls, mid); // 实例化对象
4. 调用JAVA方法
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/4.%20%E8%B0%83%E7%94%A8JAVA%E6%96%B9%E6%B3%95.jpg)
1. 获得方法ID
jmethodID smid = (*env)->GetStaticMethodID(env, cls, "sayhello_to", "(Ljava/lang/String;)I");
jmethodID mid = (*env)->GetMethodID(env, cls, "saygoodbye_to", "(Ljava/lang/String;)I");
2. 构造参数
jstring jstr = (*env)->NewStringUTF(env, "weidongshan@qq.com");
3. 调用方法
(*env)->CallStaticVoidMethod(env, jobj, smid, jstr);
ret = (*env)->CallIntMethod(env, jobj, mid, jstr);
5. 其他
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/5.%20%E5%85%B6%E4%BB%96.jpg)
设置属性
![](http://192.168.1.108/Java%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8_files/images/%E8%AE%BE%E7%BD%AE%E5%B1%9E%E6%80%A7.jpg)
jfieldID fid = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;");
jstring jstr = (*env)->NewStringUTF(env, "Bill");
(*env)->SetObjectField(env, jobj, fid, jstr);