目录
Java类包
- 使用package 定义包名,通常使用Internet域名的反序作为包名
- 使用import导入包,导入包中所有类import com.lzw.*; 但并不会指定这个包的子包的所有类。 或者导入指定类import com.lzw.Math;
- 同一个包中的类可以不放在同一个位置,只要在CLASSPATH中指定了路径
- 使用import static导入静态成员(JDK5)
final变量
- final定义的变量必须在声明时对其赋值,除了修饰基本的数据类型,还可以修饰对象引用,如数组,一旦一个对象使用final修饰,它只能恒定指向一个对象,无法将其改变指向另一个对象。一个既是static有时final的字段是一段不能改变的存储空间
- final定义的常量使用大写字母命名,中间使用下划线。final定义的变量不可改变,定义的引用不可改变,但是引用的值可以改变
- final定义的值并不是恒定不变的,例如创建空白final值,在构造方法中对其赋值;对final成员变量赋值为随机值,每次创建新的对象都会有一个随机的final成员变量值(本质上是创建了新的对象,新的对象有了新的final值)
- final可以修饰的数据
- final修饰成员变量不可更改
- final修饰成员变量定义为空白final,在构造方法中为空白final赋值
- final参数,方法内不可改变参数的值
- 方法内部设置局部变量为final,不可改变其值
package ex11_AdvancedClass;
import static java.lang.System.out;
import static java.lang.System.setOut;
import java.nio.file.FileAlreadyExistsException;
import java.util.Random;
class Test {
int i = 0;
}
public class FinalData {
private static Random rand = new Random(); //实例化一个Random类对象
private final int VALUE_1 = 9; //声明一个静态final常量,每个对象都有一份
private final static int VALUE_2 = 10; //声明一个final,static常量,归属于类,只有一份
private final Test test = new Test(); //声明一个final引用
private Test test2 = new Test(); //声明一个不是final的引用
private final int[] a = {1, 2, 3, 4}; //声明一个定义为final的数组
private final int a1 = rand.nextInt(10);
private final static int a2 = rand.nextInt(10);
private final int x; //定义空白final,可在构造方法中初始化
public FinalData(int y) {
x = y; //初始化空白final值
}
public static void main(String[] args) {
FinalData data = new FinalData(1);
// data.test = Test(): //使用final修饰的引用不可改变指向
data.test.i = 5; //不可改变引用,但可以改变引用的值(指向不可变,指向的内容可变)
data.test2 = new Test(); //没有使用final修饰的引用可以改变指向
// data.VALUE_1++; //使用final修饰的变量不可改变
// data.VALUE_2++; //使用final修饰的静态变量不可改变,一般使用FinalData.VALUE调用
data.a[0] = 9; //不可改变引用,但可以改变引用的值
out.println(data.a[0]);
//其中的final x,a1随着新对象的创建都会改变
//a2为final static,再次创建新对象并不会创建新区域,仍指向初始化时的区域,值也不会改变
out.println("static a2: " + FinalData.a2);
FinalData fdata = new FinalData(1);
out.println("fdata.a1: " + fdata.a1 + " static fdata.a2: " + fdata.a2 + " fdata.x " + fdata.x);
FinalData fdata2 = new FinalData(2);
out.println("fdata2.a1: " + fdata2.a1 + " static fdata2.a2: " + fdata.a2 + " fdata2.x " + fdata2.x);
}
}
final方法
- final定义的方法不能被重写,是因为就是定义为不能重写
- pravite定义的方法也不能被重写,是因为不能被类以外的区域访问,所以不能重写
- 区别:pravite定义的方法被隐式的指定为final类型,final类型指定的方法不能被重写但是可以被子类对象向上转型后调用。pravite类型指定的方法被子类对象向上转型后不可调用,因为pravite就是定义了不能被本类以外的区域访问,子类也不可以
final类
final定义的类不允许被继承,类中的所有方法都被隐式的设置为final形式,但是类中的成员变量可以定义为final或非final形式
内部类
- 成员内部类简介
- 内部类可以随意使用外部类的成员变量和方法,即使是private
- 内部类的对象必须绑定到外部类的对象上,内部类的对象与外部类的对象是相互依赖的
- 实例化内部对象时不能在new操作符之前使用外部类名称实例化内部类对象,而是使用外部类的对象创建其内部类的对象
- 内部类向上转型为接口
- 在内部类中实现接口,定义改该内部类为private类型(非内部类不可以定义为private或protected),在外部类中定义一个public方法,该方法返回接口类型,返回对象时内部类对象,这样就实现了内部类对象向上转型为接口。如果某个类继承了外部类
- 非内部类不能被声明为private或protected
- 使用this关键字获取内部类和外部类的引用
- 在内部类中使用this调用内部类对象的引用
- 使用外部类.this调用外部类对象的引用
- 局部内部类:在成员方法内定义内部类,如果需要在方法体内使用局部变量,需要设置成final类型,也即是在方法体内定义的内部类只能访问方法中final类型的局部变量,在内部类中,局部变量的值不可以改变。
- 匿名内部类:创建一个实现接口的匿名类的对象,在匿名内部类定义结束后需要加分号标识,标识创建接口引用表达式的标识。
- 静态内部类:内部类被声明为static
- 如果创建静态内部类的对象,不需要外部类的对象
- 不能从静态内部类的对象中访问非静态外部类的对象
- 如果在每一个java文件中都设置一个主方法,将出现很多额外代码,而程序本身不需要这些主方法,为了解决这个问题,可以将主方法写入一个静态内部类中,编译后将生成一个名为<外部类$内部类>的独立类和<外部类>,只要使用<外部类$内部类>就可以运行主方法中的内容,完成测试后,需要将所有的class文件打包时只要伸出这个独立类即可
//成员内部类
package ex11_AdvancedClass;
public class OuterClass { //外部类
innerClass in = new innerClass(); //在外部类实例化内部类的对象引用
public void outf() {
in.inf(); //在外部类中调用内部类方法
}
public innerClass doit() { //外部类方法
//y=4; //外部类不可以直接访问内部类的成员变量
in.y = 4; //可以通过对象访问
return new innerClass(); //返回内部类的引用
}
class innerClass { //内部类
int y = 0; //内部类成员变量
public innerClass() {
} //内部类构造方法
public void inf() {
} //内部类成员方法
}
public static void main(String[] args) {
OuterClass out = new OuterClass();
//内部类的对象实例化必须在外部类或外部类的非静态方法中实现
//在其他地方实现需要使用外部类。
//内部类实例一定要绑定到外部类的实例上,内部类对象依赖于外部类对象
OuterClass.innerClass in3 = out.doit(); //out对象返回内部类的引用赋值给in
//不能在new之前使用外部类名称实例化内部类对象,应该使用外部类的对象创建内部类的对象
OuterClass.innerClass in2 = out.new innerClass(); //out对象创建一个新对象赋值给in2
System.out.println(in3.y);
System.out.println(out.in);
System.out.println(out.in.y); //out对象调用过doit()方法,把它的y值设置成了4
}
}
//内部类向上转型为接口
package ex11_AdvancedClass;
interface OutInterface {
public void f();
}
public class InterfaceInner {
public static void main(String[] args) {
OuterClass2 out = new OuterClass2(); //创建外部类对象
OutInterface outinter = out.doit(); //使用外部类对象调用方法,返回内部类对象向上转型的接口
outinter.f(); //使用接口调用f()方法
}
}
class OuterClass2 {
//定义一个内部类实现OuterInterface接口
private class InnerClass implements OutInterface {
public InnerClass(String s) { //内部类的构造方法
System.out.println(s);
}
public void f() {
System.out.println("访问内部类的f()方法");
}
}
public OutInterface doit() { //定义一个外部类方法,返回值类型为OuterInterface接口类型
return new InnerClass("访问内部类构造方法"); //内部类向上转型为接口
}
}
//局部内部类
package ex11_AdvancedClass;
interface OutInterface2 {
}
class OuterClass3 {
public OutInterface2 doit(String x) {
//在doit()方法内定义一个内部类
class InnerClass2 implements OutInterface2 {
InnerClass2(String s) {
s = x; //内部类中使用局部变量必须是final变量或者实际上的final变量(不可变)
System.out.println(s);
}
}
return new InnerClass2("doit");
}
}
public class Test2 {
public static void main(String[] args) {
OuterClass3 out3 = new OuterClass3();
OutInterface2 outint = out3.doit("hi");
}
}
//匿名内部类,创建一个实现接口的匿名类的对象
class OuterClass4 {
public OutInterface2 doit() { //定义doit()方法
return new OutInterface2() { //声明匿名内部类
private int i = 0;
public int getValue() { //实现接口
return i;
}
}; // 在匿名内部类定义结束后需要加分号标识,
}
}
扫描二维码关注公众号,回复:
10151248 查看本文章