java学习笔记(韦东山)

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;
}
































  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值