方法
方法
访问权限
- public:该方法可以被所有类访问。
- private:该方法只能在定义它的类中访问。
- protected:该方法可以被同一个包中的类,或者不同包中的子类访问。
- default:如果一个方法没有使用任何访问权限修饰符,那么它是 package-private 的,意味着该方法只能被同一个包中的类可见。
抽象方法
- 没有方法体的方法被称为抽象方法,它总是在抽象类中声明。
abstract class AbstractDemo {
abstract void display();
}
- 当一个类继承了抽象类后,就必须重写抽象方法
public class MyAbstractDemo extends AbstractDemo {
@Override
void display() {
System.out.println("重写了抽象方法");
}
public static void main(String[] args) {
MyAbstractDemo myAbstractDemo = new MyAbstractDemo();
myAbstractDemo.display();
}
}
可变参数
-
可变参数是 Java 1.5 的时候引入的功能,它允许方法使用任意多个、类型相同(
is-a
)的值作为参数 -
可变参数必须要在参数列表的最后一位
-
避免重载带有可变参数的方法
native方法
JNI使用场景
- 标准的 Java 类库不支持。
- 已经用另一种语言,比如说 C/C++ 编写了一个类库,使用 Java 代码调用
- 某些运行次数特别多的方法,为了加快性能,需要用更接近硬件的语言(比如汇编)编写。
JNI缺点
- 程序不再跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言部分。
- 程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。一个通用规则是,你应该让本地方法集中在少数几个类当中。这样就降低了 Java 和 C/C++ 之间的耦合性。
JNI语法
- 修饰方法的位置必须在返回类型之前,和其余的方法控制符前后关系不受限制。
- 不能用 abstract 修饰,也没有方法体,也没有左右大括号。
- 返回值可以是任意类型
用C语言编写程序本地方法
①、编写带有 native 方法的 Java 类,生成.java 文件;
public class HelloJNI {
static {
// 加载名为libhello.dylib的动态链接库
System.loadLibrary("hello");
}
// 定义本地方法
private native void helloJNI();
public static void main(String[] args) {
// 调用本地方法
new HelloJNI().helloJNI();
}
}
②、使用 javac HelloJNI.java
命令编译所编写的 Java 类,生成.class 文件;
③、使用 javac -h . .\HelloJNI.java
类名 生成扩展名为 h 的头文件,也即生成 .h 文件;
④、使用 C/C++(或者其他编程想语言)实现本地方法,创建 .h 文件的实现,也就是创建 .cpp 文件实现.h 文件中的方法;
⑤、将 C/C++ 编写的文件生成动态连接库,生成 dll 文件;
构造方法
- 当一个类被实例化的时候,就会调用构造方法。只有在构造方法被调用的时候,对象才会被分配内存空间。每次使用
new
关键字创建对象的时候,构造方法至少会被调用一次。
构造方法规则
- 构造方法的名字必须和类名一样;
- 构造方法没有返回类型,包括 void;
- 构造方法不能是抽象的(abstract)、静态的(static)、最终的(final)、同步的(synchronized)。
- 可以使用访问权限修饰符(private、protected、public、default)来修饰构造方法
class class_name {
// 默认无参构造方法
public class_name(){}
// 定义有参数列表的构造方法
public ciass_name([paramList]){}
…
// 类主体
}
- 默认构造方法的目的主要是为对象的字段提供默认值
复制对象
通过构造方法
public class CopyConstrutorPerson {
...
public CopyConstrutorPerson(CopyConstrutorPerson person) {
this.name = person.name;
this.age = person.age;
}
...
}
通过对象的值
CopyValuePerson p2 = new CopyValuePerson();
p2.name = p1.name;
p2.age = p1.age;
通过Object类的clone()方法
- 通过
clone()
方法复制对象的时候,ClonePerson 必须先实现 Cloneable 接口的clone()
方法,然后再调用clone()
方法(ClonePerson p2 = (ClonePerson) p1.clone()
)。