一、代码块
-
什么是代码块
-
代码块是类的成分之一:成员变量,方法,构造器,代码块,内部类
-
标准类{ 成员变量; 构造方法; 成员方法; 代码块; 内部类; }
-
代码块在Java中如何表示
-
在Java中,使用{}括起来的代码成为代码块(Code block)
-
-
代码块的分类
-
根据其位置和声明的不同,可以分为:
-
局部代码块:用于限定变量生命周期,及早释放,提高内存利用汇率
-
静态代码块:主要用于对静态属性进行初始化
-
实例(构造)代码块:调用构造方法都会执行,并且在构造方法前执行
-
同步代码块:一种多线程保护机制
-
-
局部代码块
-
在方法中出现,可以限定变量生命周期,及早释放,提高内存利用率。
-
{}出现在方法内,那么该大括号就被称为局部代码块
-
package 局部代码块; public class Demo { public static void main(String[] args) { //局部代码块 { int a = 100; } //{}出现在方法内,那么该大括号就被称为局部代码块 //在方法中出现,可以限定变量生命周期,及早释放,提高内存利用率。 } }
-
静态代码块
-
必须有static修饰,必须放在类中方法外
-
与类一起加载执行,并且静态代码块只执行一次
-
给静态成员初始化
-
public class Test { public static void main(String[] args) { A a = new A(100); } } //寻常给静态成员赋初始化值 class A{ static int a =100; //构造方法 public A(){} public A(int a){ this.a=a; } }
package 静态代码块; public class Test { public static void main(String[] args) { System.out.println(A.a); } } //静态代码块给变量赋初始化值 class A{ static int a ; static { a =100; //不需要再定义int System.out.println("我是静态代码块"); } }
-
特点
-
每次执行类,加载类的时候都会先执行静态代码块一次
-
静态代码块是自动触发执行的,只要程序启动静态代码块就会先执行一次
-
在启动程序之前可以做资源的初始化,一般用于初始化静态资源。
-
-
实例代码块
-
没有static修饰,必须放在类中方法外。
-
与对象初始化一起加载
-
即每次调用构造方法都会执行,并且在构造方法前执行。
-
package 构造代码块; public class Demo { public static void main(String[] args) { new A(); new A(); } } class A{ public A(){ System.out.println("A"); } { System.out.println("我是构造方法代码块"); } }
-
特点
-
无static修饰。属于对象,与对象的创建一起执行的。
-
每次调用构造器初始化对象,实例代码块都要自动触发执行一次。
-
实例代码块实际上是提取到每一个构造器中去执行的。
-
-
-
实例代码块中的内容在构造方法前执行。
-
-
注意:
-
-
类的成员定义,和顺序无关
-
-
静态代码块、构造代码块、构造函数执行顺序
-
父类静态代码块>子类静态代码块>main()方法>父类代码块>父类构造器>子类代码块>子类构造器
-
静态代码块:类的加载。字节码文件进代码区
-
main: JVM自动的调用main方法
-
代码块、构造器:初始化过程(创建对象过程)
-
package 代码快运行顺序; public class Demo extends A { public static void main(String[] args) { System.out.println("我是main方法"); Demo demo = new Demo(); System.out.println("我第二次的mian方法"); Demo demo1 = new Demo(); } static { System.out.println("我是子类静态代码块"); } { System.out.println("我是子类构造代码块"); } public Demo(){ System.out.println("我是子类的构造器"); } } class A{ static { System.out.println("我是父类静态代码块"); } { System.out.println("我是父类构造代码块"); } public A(){ System.out.println("我是父类的构造器"); } }
-
同步代码块
-
多线程才遇到
-
二、包
-
什么是包?
-
包就是文件夹==根据包名自动生成class文件的存放路径
-
类如果有package关键字,运行或者使用类的时候,就不能只写类名了;要写包名+类名:全限定路径名
-
-
包的三大作用
-
区分相同名字的类。同一个文件夹下不能出现同名的文件,因此把两个同名的类分别放在两个包中,就相当于是放在两个文件夹中。
-
当类很多时,可以方便的管理类。
-
控制访问范围。权限修饰符
-
-
包的基本语法
-
package是关键字,表示打包;后面的是包名。必须代码的第一行
package java.util;
-
使用包中的类
-
以ArrayList类为例,如果想要使用java.util中的ArrayList类,有两种方式:
-
-
-
使用import,即放一个import语句在文件的最前面:
-
格式:
-
-
import 包名.类名;
-
-
package a.b; import x.y.A; public class Demo{ public static void main(String[] args) { A a = new A(); System.out.println(a); } }
-
-
直接在程序中打出ArrayList的全名,不管在哪里,只要使用了就打出全名。
-
package a.b; //import x.y.A; public class Demo{ public static void main(String[] args) { x.y.A a = new x.y.A(); System.out.println(a); } }
-
包的命名规则
-
只能包含数字、字母、下划线和“.”,但是不能用数字开头,不能是关键字;合法的标识符
-
-
demo.class.ex1 //错误的!因为class是关键字
-
demo.12a.ex1 //错误的!因为12a是数字开头
-
demo.a12.ex1 //正确的!
-
-
命名规范
-
一般都是小写字母+“.”。
-
普遍的命名方式都是:公司域名倒写.项目名.业务模块名
-
-
eg: com.sina.crm.user //用户模块
-
com.sina.crm.order //订单模块
-
com.sina.crm.utils //工具类
-
-
常见包
-
java.lang //lang包是基础包,默认引入,不需要再引入
-
java.util //util包是系统提供的工具包,里面有很多工具类
-
java.net //网络包,用于网络开发的
-
java.awt //是做java的界面开发,GUI
-
java.sql //数据库
三、修饰符 :Java :类 变量 方法
-
什么是修饰符?
-
修饰符用来修饰 类、方法、变量
-
通常放在语句的最前端
-
-
修饰符的分类
-
权限(访问)修饰符
-
非权限修饰符
-
-
访问修饰符
-
Java中,可以使用访问修饰符来保护对类、变量、方法和构造方法的访问(使用、赋值、取值、调用)。Java支持4种不同的访问权限。
-
-
public:公有访问。对所有的类都可见。
-
protected:保护型访问。对同一个包可见,对不同的包的子类可见。
-
default:默认访问权限。只对同一个包可见,注意对不同的包的子类不可见。
-
private:私有访问。只对同一个类可见,其余都不见。
-
-
非访问权限修饰符
-
常用的有以下几种:
-
-
static 修饰符:不能修饰类;只能修饰 方法 变量
-
final 修饰符,用来修饰类、方法和变量
-
-
final 修饰的类不能够被继承
-
修饰的方法不能被继承类重新定义
-
修饰的变量为常量,是不可修改的。
-
-
abstract修饰符,用来创建抽象类和抽象方法。
-
-
-
synchronized 用于多线程的同步。
-
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
-
transient:序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
-
-
修饰符作用
类修饰符
外部类修饰符
-
public(访问控制符),将一个类声明为公共类,它可以被任何对象访问,一个程序的主类必须是公共类。
-
default(访问控制符),类只对包内可见,包外不可见。
-
abstract(非访问控制符),将一个类声明为抽象类,抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充,抽象类可以包含抽象方法和非抽象方法。
-
final(非访问控制符),将一个类生命为最终(即非继承类),表示它不能被其他类继承。
注意:
protected 和 private 不能修饰外部类,是因为外部类放在包中,只有两种可能,包可见和包不可见。
final 和 abstract不能同时修饰外部类,因为该类要么能被继承要么不能被继承,二者只能选其一。
不能用static修饰,因为类加载后才会加载静态成员变量。所以不能用static修饰类和接口,因为类还没加载,无法使用static关键字。
内部类修饰符
-
内部类与成员变量地位一直,所以可以public、protected、default和private,同时还可以用static修饰,表示嵌套内部类,不用实例化外部类,即可调用
方法修饰符
-
public(公共控制符),包外包内都可以调用该方法。
-
protected(保护访问控制符)指定该方法可以被它的类和子类进行访问。
-
default(默认权限),指定该方法只对同包可见,对不同包(含不同包的子类)不可见。
-
private(私有控制符)指定此方法只能有自己类等方法访问,其他的类不能访问(包括子类),非常严格的控制。
-
final,指定方法已完备,不能再进行继承扩充。
-
static,指定不需要实例化就可以激活的一个方法,即在内存中只有一份,通过类名即可调用。
-
synchronize,同步修饰符,在多个线程中,该修饰符用于在运行前,对它所属的方法加锁,以防止其他线程的访问,运行结束后解锁。
-
native,本地修饰符。指定此方法的方法体是用其他语言在程序外部编写的。
-
abstract,抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。==抽象方法不能被声明成final 和 static。==任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。抽象方法的声明以分号结,例如:public abstract sample(); 。
变量修饰符
-
成员变量修饰符
-
public(公共访问控制符),指定该变量为公共的,它可以被任何对象的方法访问。
-
protected(保护访问控制符)指定该变量可以别被自己的类和子类访问。在子类中可以覆盖此变量。
-
default(默认权限),指定该变量只对同包可见,对不同包(含不同包的子类)不可见。
-
private(私有访问控制符)指定该变量只允许自己的类的方法访问,其他任何类(包括子类)中的方法均不能访问。
-
final,最终修饰符,指定此变量的值不能变。
-
static(静态修饰符)指定变量被所有对象共享,即所有实例都可以使用该变量。变量属于这个类。
-
transient(过度修饰符)指定该变量是系统保留,暂无特别作用的临时性变量。不持久化。
-
volatile(易失修饰符)指定该变量可以同时被几个线程控制和修改,保证两个不同的线程总是看到某个成员变量的同一个值。
-
注意:final 和 static 经常一起使用来创建常量。
-
局部变量修饰符
-
-
只能使用 final 修饰局部变量
-
-
为什么不能赋予权限修饰符?
-
-
因为局部变量的生命周期为一个方法的调用期间,所以没必要为其设置权限访问字段,既然你都能访问到这个方法,所以就没必要再为其方法内变量赋予访问权限,因为该变量在方法调用期间已经被加载进了虚拟机栈,换句话说就是肯定能被当前线程访问到,所以设置没意义。
-
-
为什么不能用static修饰?
-
-
我们都知道静态变量在方法之前先加载的,所以如果在方法内设置静态变量,可想而知,方法都没加载,你能加载成功方法内的静态变量?
-
-
-
接口修饰符
-
接口修饰符
-
-
接口修饰符只能用public、default和abstract,不能用final、static修饰。
-
接口默认修饰为abstract。
-
-
接口中方法修饰符
-
-
只能用 public abstract修饰,当然如果你什么都不写,默认就是public abstract。
-
注意:在Java1.8之后,接口允许定义具体方法了
-
-
static
-
default
-
-
四:内部类
-
什么是内部类
-
将一个类定义在另一个类的里面或者定义在一个方法的内部,把该类就称之为内部类;内部类也是对封装的一种体现。
-
类中定义类
package 内部类1; public class Demo { } class A{ class B{ //B为内部类 } }
-
注意
-
定义在class 类名{}花括号外部的,即使是在一个文件里,也不能称为内部类
-
内部类和外部类共用同一个java的源文件,但是经过编译之后,内部类会形成自己单独的字节码文件;
-
-
$
-
-
内部类分类
-
根据内部类定义位置的不同,可以将内部类分为
-
-
成员内部类
-
而成员内部类又根据是否被static修饰分为
-
普通内部类
-
静态内部类;
-
-
-
局部内部类
-
匿名内部类
-
-
成员内部类
-
普通内部类
-
-
未被static修饰的成员内部类就称为普通内部类;
package 普通内部类; public class Demo { } class A{ //类中方法外 class B{ } }
-
初始化内部类格式
-
-
成员
-
-
属性
-
行为
-
-
外部类.内部类 变量名 = new 外部类().new 内部类()
package 内部类; //初始化类的使用 public class Demo { public static void main(String[] args) { A.B v =new A().new B(); System.out.println(v.a); v.m(); } } class A{ class B{ int a =100; public void m(){ System.out.println("十步杀一人,千里不留行"); } } }
总结:
-
外部类中的任何成员都可以在普通内部类方法中直接被访问
-
普通内部类所处的成员与外部类成员位置相同,因此也受public、private等访问限定符的约束;其他类
-
在内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,需采用:
外部类名称.this.同名成员名
-
普通内部类对象必须在先有外部类对象前提下才能被创建;
-
外部类中不能直接访问内部类中的成员,如果要访问必须先要创建内部类的对象;
-
注意
-
-
在Java中,所有的变量定义,可以写在类中方法外
-
但是,其他代码(操作)必须要有代码承载
-
-
静态内部类
-
被static修饰的内部成员类就称为静态内部类;
package 静态内部类; public class out { //out是外部类 static int a ; static int b ; //静态成员变量b public void methodA(){ a=10; System.out.println(a); } public static void methodB(){ System.out.println(b); } //in就是静态内部类 static class in{ public void methodInner(){ // 在内部类中只能访问外部类的静态成员变量及方法 // a=100; 编译失败,原因:a不是外部类中的静态成员变量 // methodA(); //编译失败,原因:methodA()不是静态类成员方法 b=100; methodB(); } public static void main(String[] args) { //静态成员变量访问:类名.成员变量名 System.out.println(out.b); // 静态内部类对象的创建 //不需要借助外部类对象 in ic=new in(); // 静态成员方法访问 ic.methodInner(); } } }
-
局部内部类(不常用)
定义在外部类的方法体或者代码块{}中,该种内部类只能在其定义的位置进行使用,其他位置均不能使用;
总结:
-
局部内部类只能在所定义的方法体内部使用;
-
不能被public、static等修饰符修饰;
-
不能在局部内部类中定义静态成员;
-
局部内部类不能被public、static等访问限定符修饰,若加上修饰符,就会报错
-
匿名内部类
-
匿名内部类,就是没有名字的一种嵌套类。它是Java对类的定义方式之一。
package 匿名内部类; public class Demo { } class A{ public void m(){ new A(){ public void ma() { System.out.println(); } }; } }
-
为什么要使用匿名内部类
-
快速实例化接口或者抽象类
-
package 匿名内部类使用;
public class Demo {
public static void main(String[] args) {
A a= new A(){
@Override
public void m() {
System.out.println("封狼居胥");
}
};
a.m();
B b = new B(){
@Override
public void n() {
System.out.println("想当年,金戈铁马,气吞万里如虎");
}
};
b.n();
}
}
interface A{
public void m();}
abstract class B{
public abstract void n();
}
-