对象与引用
Java语言中除基本类型外的变量类型都称为引用类型。
Java中的对象都是通过引用对其操作的。
例:Car car = new Car();
右边的"new Car",是以Car类为模板,调用Car类的构造函数,在堆空间中创建一个Car类型;
左边的"Car car"创建了一个Car类的引用变量,所谓Car类的引用,就是以后可以用来指向Car对象的对象引用;
"="操作符使对象引用指向刚创建的那个Car对象;
拆分一下:即 Car car;
car = new Car();
这里有两个实体:一是对象引用变量,一是对象本身.
简单来说:
new Car(); 这个语句在堆空间里创建了实体,尽管它们也是确确实实存在的实体,但是,我们看不见,也摸不着。
对象没有名字,也就没法直接访问它。我们需要通过对象引用来间接访问对象。
对象好比是一只很大的气球,但是我们抓不住它。引用变量是一根绳,可以用来系汽球。
Car car1; (1)创建一根绳子,一根还没有系上任何一个汽球的绳;
Car car2;(2)就又做了一根绳,还没系上汽球,
car1 = new Car();(3)给car1 系上气球;
car2 = car1 ;(4)这里,发生了复制行为。要说明的是,对象本身并没有被复制,被复制的只是对象引用。
结果是,car2也指向了car1所指向的对象。两根绳系的是同一只汽球。
基本类型和引用类型的区别
名称 | 概念 | 存储位置 |
---|---|---|
基本数据类型 | 变量(单纯的值) | 在栈中存储 |
引用数据类型 | 对象(引用) | 在栈中存引用,在堆中存具体对象属性 |
值传递与引用传递
1.值传递(形式参数是基本数据类型):
用实际参数值赋给方法的形式参数,实质上只是给方法的形参初始化了一个值,这时再调用方法运行,方法会在虚拟机栈中单独开辟一个空间运行,方法中对值的操作与实际参数无关,对实际参数的值无影响.
2.引用传递(形式参数是引用数据类型):
实质上是传地址,实际参数会将对象引用(即地址)传递给方法中的形式参数,这时方法中的操作实质上都是在对象中进行操作,即方法执行过程的结果都会被对象保留下来,方法执行中形参改变实参也会改变.
代码示例
public class Test { //定义一个Test类
int i ; //成员变量i
void change(int i){ //无返回值方法change,形式参数i,会用形式参数的值来初始化自己得存储单元格,和实参是两个不同的存储单元,方法执行中形参值改变不影响实际参数值
i++; //方法内执行
System.out.println(i);//方法内输出,1
}
void change1(Test t){ //无返回值方法change1,形式参数是引用数据类型,实参会把对象引用(即地址)传递过来,故在此方法中的所有操作实质上都是在对象上进行的,方法执行中形参值改变实参也会改变.
t.i++;
System.out.println(t.i);
}
public static void main(String[] args) {//main方法
Test ta = new Test();//创建一个对象Test(),并用ta指向Test的对象引用
System.out.println(ta.i); //输出了成员变量i,默认值为0
ta.change(ta.i);//调用change方法,传入值0,实质上只是把change中的形参值进行了初始化,对自身并无影响
System.out.println(ta.i); //输出的值仍是0
ta.change1(ta); //将对象Test直接传入change1中,形参中的操作是在对对象操作,会被保存下来,改变实参
System.out.println(ta.i);//输出为1
}
}
static关键字
概念:static关键字又被称作是静态,可以用来修饰类的属性、方法、代码块和内部类。
特点:
随着类的加载而加载;
优先于对象而生成;
修饰的成员被所有对象所共享;
可以不创建对象,直接被类调用。
static属性:静态属性被类的所有对象共享,不管创建多少对象,静态属性在内存中都只存在一个。
注意:
静态方法只能访问静态变量;
成员方法既能访问成员变量又能访问静态变量;
静态方法技能被对象调用,也能使用类名调用,建议使用类名调用。
代码示例1:
public class Chinese {
String name;//成员变量,每个对象都复制一份
int age;
static String country = "中国";//静态方法,随着类的加载而加载,所有对象共享,在内存中只有一份
public static void main(String[] args){
Chinese zs = new Chinese();
zs.name = "张三";
zs.age = 18;
System.out.println(zs.name);
System.out.println(zs.age);
System.out.println(zs.country);//通过对象调用
System.out.println(Chinese.country);//通过类名调用,省去了创建对象的步骤,建议使用
Chinese ls = new Chinese();
ls.name = "李四";
ls.age = 28;
System.out.println(ls.name);
System.out.println(ls.age);
System.out.println(ls.country);
System.out.println(Chinese.country);
}
示例代码2:
public class StaticMethod {
String name;//成员变量
static String name1; //静态变量
public static void a(){
System.out.println(name1);//静态方法只能访问静态变量
}
public void b(){
System.out.println(name);//成员方法既可以访问成员变量
System.out.println(name1);//也可以访问静态变量
}
public static void main(String[] args) {
StaticMethod.a(); //通过类名直接调用静态方法
}
}
代码块
概念:代码块在类中进行声明,就像是一个没有名称的方法体(代码块),分为实例块和静态块。
实例块:每次在创建时自动执行
{
//符合语法的java代码
}
静态块:类加载时自动调用,仅一次,与是否创建对象无关
{
//符合语法的java代码
}
代码示例
//代码块:类似一个没有名称的方法
public class CodeDemo {
//实例块:创建时自动执行
{
System.out.println("实例代码块");
}
//静态块:随类一起加载的
static{
System.out.println("静态代码块");
}
public static void main(String[] args) {
new CodeDemo();//注释掉之后只有静态代码块输出
}
}
包(package)
包的简单理解就是文件夹。
作用:管理类
具体体现:
避免重名类 使用全类名:全类名=包名(类的地址)+类名
按照不同的功能管理类 如:数据访问层包/控制层包/工具包......
控制访问权限
包的命名规范:
在包名中,可以使用.号来区分包的级别;包名一般情况下是小写;
第一级 指项目的类型,如:com,org,gov,edu等(com公司,org公益组织,gov政府,edu教育);
第二级 指项目所开发或者运行公司的名称,如oracle,sun,huawei等;
第三级 指项目的名称,如:bcms,oa,erp,cms等;
第四级 指项目模块的名称,如:bean,action,exception,dao,util等;
......
包可以更好的管理逻辑相关的类,可以控制不同包之间的访问权限;
导入外部包的类,关键字"import"
访问权限修饰符
Java中有四个访问权限修饰符,权限从大到小依次为
1.public
公共权限;
修饰类,属性,方法;
可以被任意类访问。
2.protected
受保护权限;
修饰属性,方法;
可以被同一个包下的类访问,如果不是同包类,必须是该类的子类才能访问。
3.default(默认 无)
同包权限;
修饰类,属性,方法;
只能被同包类访问。
4.private
私有权限;
修饰属性,方法;
只能在同一个类中被访问。
测试—1
package fang_wen_quan_xian;
//访问权限修饰符
public class Test {
public String pub = "public";//public
protected String pro = "protected";//prodected
String def = "default";//default
private String pri = "private";//private
public static void main(String[] args) {
Test data = new Test();
System.out.println(data.pub);
System.out.println(data.pro);
System.out.println(data.def);
System.out.println(data.pri);
}
}
测试—2
package fang_wen_quan_xian;
//测试权限修饰符
public class Test1 {
public static void main(String[] args) {
Test data = new Test();
System.out.println(data.pub);
System.out.println(data.pro);
System.out.println(data.def);
// System.out.println(data.pri); 私有权限,无法检索到
}
}
测试—3
package fang_wen;
import fang_wen_quan_xian.Test;
//测试访问权限符
public class Test2 extends Test {
public static void main(String[] args) {
Test2 data = new Test2();
System.out.println(data.pub);
System.out.println(data.pro);//若要在不同包使用,需要继承父类
// System.out.println(data.def);不可检索
// System.out.println(data.pri);不可检索
}
}