1.垃圾处理机制
引用数据类型的变量被置为null后,java的垃圾处理机制会将引用数据类型所指向的堆空间释放。
2. 类型转换。
short s = 1;
s = s + 1; // 出错,因为对于byte,short的运算,为了保证精度,会自动转换为int类型, 右边的s+1变成了int类型,左边还是short类型,会导致精度异常
3.构造块:
在一个类中用{}括起来的一片代码块
class Person {{
// 构造块
// 每实例化一个对象前,都执行;先于构造方法执行
}
}
每去new一个对象,这个大括号括起来的语句会被调用,构造块会比构造方法先执行
4.静态代码块:
在大括号之前用static修饰的一片代码块
class Person {static {
// 静态块
// 实例化第一个对象前,执行;只执行一次
。。。
}
}
例如一般的java程序的就是用static修饰的,如下所示:public class Oop5 {
public static void main(String args[]) {
; 。。。
}
}
就是静态代码块,不需要new就可以执行
5.面向对象的三大特性:
封装性:把属性/方法封装为一个整体,同时也有权限的限制
继承性:为了复用代码
限制:儿子无法直接操作父亲的私有属性
儿子无法使用父亲的私有方法
儿子不能私吞祖传的方法(复写父类的方法,将该方法设置为private,这样编译都过不了)
6.
子类重写了父类的方法,叫做复写
7.
实例化子类对象时,先调用父类的构造方法,再调用子类的构造方法
子类的构造方法里会默认调用super(),如果要指定带参数的,就要在super中指定,没有指定就调用super().
8.
抽象类:
abstract class 类名 {
属性;
普通方法 { }
// 抽象方法
访问权限 abstract 返回值类型 方法名 (参数) ; /* 只需要声明,不需要实现 */
}
作用:规定子类必须实现的方法,起“模板”作用
不能实例化对象
子类必须覆写全部抽象方法
9.
接口: 为了突破单继承
// 接口由全局常量、公共的抽象方法组成
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; }
}
10.
异常:
throw:写在方法的声明位置,表示如果发生异常,扔给调用者处理
public 返回值 方法名(参数列表……) throws 异常类 {
。。。
}例子:
public int div (int m, int n) throws Exception {
......
}
如果在被调用的方法中有异常并且被处理,调用的方法中就没有异常出现,如果既要被调用方法和
调用方法中都处理异常,那么就要在被调用方法中手动调用throw e来抛出异常
如果try或catch块中有return或throw语句,会先执行finally块,再返回来执行return或throw语句
11.
package a.b.c.d
表示编译生成的.class类放在a/b/c/d文件夹下面
作用:解决类的同名冲突问题
将生成的class压缩为.jar文件:jar -cvf <file.jar> <dir>
查看:jar -tvf <file.jar>
解压:tar -xvf <file.jar>
CLASSPATH:
指定编译时查找源码的目录
指定运行时查找的“.class文件的目录”或“jar文件”
设置方法:
export CLASSPATH=<dir1>:<dir2>:....:<file1.jar>:<file2.jar>:...
用于可能找不到类的错误:
java.lang.NoClassDefFoundError: a/b/c/d1/Math
at Pack.main(Pack.java:9)
Caused by: java.lang.ClassNotFoundException: a.b.c.d1.Math
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 1 more
12.
权限:
类:
public的类可以被其他包访问
一般的类只能在本包中访问(同一个文件夹)
类的成员:
private:本类可以访问
default: 本包可以访问
protected:本包,其他包的子类可以访问
public: 所有,其他包的非子类也可以访问
13.内部类:
定义内部类的作用:可以通过内部类来访问外部类的私有属性
在类的内部定义一个类
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( );
匿名内部类:
new候直接实现接口中的方法,直接使用
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!");
}
});
}
}
14.使用JNI:
JAVA代码
public class JNIDemo {
//静态代码块,在运行之前就会第一个运行该段代码,并且只执行一次
static { /* 1. load */
System.loadLibrary("native"); /* libnative.so */
}
//声明了native层的code
public native void hello();
public static void main (String args[]) {
JNIDemo d = new JNIDemo();
/* 2. map java hello <-->c c_hello */
/* 3. call */
d.hello();
}
}
Native代码:
#include <jni.h> /* /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ */
#include <stdio.h>
#if 0
typedef struct {
char *name; /* Java里调用的函数名 */
char *signature; /* JNI字段描述符, 用来表示Java里调用的函数的参数和返回值类型 */
void *fnPtr; /* C语言实现的本地函数 */
} JNINativeMethod;
#endif
void c_hello(JNIEnv *env, jobject cls)
{
printf("Hello, world!\n");
}
static const JNINativeMethod methods[] = {
{"hello", " ()V", (void *)c_hello},
};
/* System.loadLibrary */
// JNI_Onload在java层调用System.loadLibrary之后就会被调用到
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;
if ((*jvm)-> GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
return JNI_ERR; /* JNI version not supported */
}
cls = (*env)-> FindClass(env, " JNIDemo");
if (cls == NULL) {
return JNI_ERR;
}
/* 2. map java hello <-->c c_hello */
if ((*env)-> RegisterNatives(env, cls, methods, 1) < 0)
return JNI_ERR;
return JNI_VERSION_1_4;
}
编译:
javac JNIDemo.java
编译java
gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so native.c
/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/是<jni.h>的路径
-shared:编译动态库
-o 指定目标名称
export LD_LIBRARY_PATH=.
指定加载的so库为当前目录
java JNIDemo
编译c库:-I指定了库
method中的类型指定可以根据一个取巧的方法:
可以使用 javah -jni JNIDemo的方法来生成一个头文件,打开头文件可以看到:Signature: ()V,如下所示,就可以将该Signature在method中表示了
/*
* Class: JNIDemo
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_JNIDemo_hello
(JNIEnv *, jobject);
java和c之间进行数据传递:
传递基本数据:直接使用,直接返回
传递字符串:
以下函数从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);
}
传递数组:
以下函数从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;
}