Java入门系列-14-深入类和对象
这篇文章用大量的代码帮你搞懂:值传递和引用传递、构造方法、方法重载、static关键字的使用
方法参数传递-值传递和引用传递
1.值传递
敲一敲:
/** * 使用方法交换两个变量的值 * @author Jack * */ public class Swap { public static void main(String[] args) { int a=10; int b=8; Swap swap=new Swap(); swap.swap(a, b); System.out.println("调用方法后:a="+a+",b="+b); } public void swap(int a,int b) { int temp=a; a=b; b=temp; System.out.println("交换后:a="+a+",b="+b); } }
在上面这段代码中我们发现在方法内部对这两个参数进行交换成功,但是在调用方法后外部变量并没有任何变化。参数的类型为值类型,使用值类型作为参数称为值传递。
值传递方法内部修改外部不保留,参数内的变量是实参的副本。
2.引用传递
敲一敲:
import java.util.Arrays; public class Swap2 { public static void main(String[] args) { int[] ages= {1,2,3}; Swap2 swap=new Swap2(); System.out.println("调用change前:"+Arrays.toString(ages)); swap.change(ages); System.out.println("调用change后:"+Arrays.toString(ages)); } public void change(int[] ages) { ages[0]=100; } }
在方法内部对参数变量进行修改后,方法的外部打印后也进行了修改,数组、类都是引用类型,使用引用类型作为参数传参被称为引用传递。
引用传递方法内部修改外部保留,参数内的变量是对实参的引用。
构造方法
在创建对象的时候,我们使用过这样的代码 类名 对象名=new 类名();
,其实这时就是在调用此类的构造方法 public 类名(){}
。
构造方法又称构造函数,是类中一种特殊的方法。构造方法名与类名相同,不返回任何值,主要完成对象的初始工作。
语法:
访问修饰符 构造方法(可以指定参数){ //初始化代码 }
敲一敲:无参构造方法
public class Student { String name; int age; public Student() { name="张三"; age=18; } public static void main(String[] args) { Student stu=new Student(); System.out.println(stu.name); System.out.println(stu.age); } }
这样就能在 new 时给对象的属性初始化值,但是在每一次 new 的时候都是相同的值。能不能在 new 的同时指定值呢?那就是使用有参的构造方法。
敲一敲:有参构造方法
public class Student { String name; int age; public Student(String name,int age) { this.name=name; this.age=age; } public static void main(String[] args) { Student stu=new Student("张三",12); System.out.println(stu.name); System.out.println(stu.age); } }
this 代表当前对象的引用,在有参构造方法中使用时区分属性和参数
上面的这段代码,能不能这样创建对象 Student stu=new Student();
答案是不可以的
不显式编写构造方法,系统将默认提供无参构造方法
一旦提供编写构造方法,系统便不再提供无参构造方法
所以这时我们可以同时编写有参构造方法和无参构造方法,使我们创建对象的时候更加的灵活。
敲一敲:同时提供有参和无参构造方法
public class Student { String name; int age; //无参构造方法 public Student() {} //有参构造方法 public Student(String name,int age) { this.name=name; this.age=age; } public static void main(String[] args) { //使用有参构造方法 Student stu1=new Student("张三",12); System.out.println(stu1.name); System.out.println(stu1.age); //使用无参构造方法 Student stu2=new Student(); stu2.name="李四"; } }
方法重载
在上一部分中,我们使用了有参和无参的方法,为什么在一个类中可以定义多个类名相同的方法呢?因为实现了方法重载。只不过构造方法重载是一种特殊的重载。
重载的条件(两同两不同)
在同一个类中,方法名相同,参数类型不同,参数个数不同
敲一敲:实现普通方法的重载
public class Teacher { public void teach(String project) { System.out.println("教授科目:"+project); } public void teach(String project1,String project2) { System.out.println("教授科目:"+project1+" 和 "+project2); } public static void main(String[] args) { Teacher t=new Teacher(); t.teach("语文"); t.teach("语文","数学"); } }
在生活中有很多活动就属于重载,比如 表演 ,给表演者剧本就是在表演戏剧,给表演者乐器,就是表演演奏,给表演者话筒,就是表演相声。
在代码中使用重载也有很多好处,比如 System.out.println();
这个方法也有很多重载形式,可以传入 int string object 作为参数,减少了书写和记忆的成本。你肯定不希望打印每种数据类型时都单独定义一个方法,像后面这样 printIntln(int out)
printDoubleln(double out)
printLongln(long out)
……
this 关键字的用法
在使用构造函数时使用了 this 关键字用于区分属性和参数,那只是第一种用法,除此之外还可以调用方法、调用构造方法。
调用属性:this.health=100;
调用方法:this.print();
调用构造方法:this();
this("张三",18);
必须用在构造方法中的第一行
static 关键字的用法
如何通过类名直接访问类中的成员,像之前用过的 Arrays.toString()
,查看源码部分代码如下。
public static String toString(int[] a) { if (a == null) return "null"; int iMax = a.length - 1; if (iMax == -1) return "[]"; StringBuilder b = new StringBuilder(); b.append('['); for (int i = 0; ; i++) { b.append(a[i]); if (i == iMax) return b.append(']').toString(); b.append(", "); } }
当前这个方法使用了 static
关键字进行了修饰
还可以修饰成员变量:
public class Teacher { static final String SEX_MALE="男"; static final String SEX_FEMALE="女"; String sex; public static void main(String[] args) { Teacher teacher=new Teacher(); teacher.sex=Teacher.SEX_FEMALE; System.out.println(teacher.sex); } }
final 修饰后的变量都将变成常量
常量的值不能修改,只能使用
可以修饰代码块:
public class Teacher { static final String SEX_MALE="男"; static final String SEX_FEMALE="女"; String sex; //代码块 static { System.out.println("静态代码块"); } public static void main(String[] args) { Teacher teacher=new Teacher(); teacher.sex=Teacher.SEX_FEMALE; System.out.println(teacher.sex); } }
static 关键字使用注意事项
1.static 修饰了属性和代码块后,会先初始化静态属性,再执行静态代码块
public class TakeCare1 { static String name="aa"; static { System.out.println(name); System.out.println("静态代码块执行"); } public TakeCare1() { System.out.println("构造函数执行"); } public static void main(String[] args) { TakeCare1 t=new TakeCare1(); } }
2.static 关键字不能修饰局部变量
public class TakeCare2 { public static void main(String[] args) { static int a=10; } }
3.同一个类中的静态方法可以互相通过方法名直接调用
public class TakeCare2 { public static void test1() { System.out.println("method test1"); test2(); TakeCare2.test2(); } public static void test2() { System.out.println("method test2"); } public static void main(String[] args) { test1(); } }
4.不同类中的静态成员调用需要通过 类名.成员
调用
public class TakeCare4 { public static void main(String[] args) { Test.test(); System.out.println(Test.name); //test();//去掉前面注释试试 } } class Test{ static String name="Test"; public static void test() { System.out.println("method test"); } }
5.同一个类中非静态方法可以直接通过 属性名或方法名 调用
public class TakeCare5 { static String name="static property"; public static void st() { System.out.println("static method"); } public void test() { System.out.println("instance method"); System.out.println(name); st(); } }
6.静态方法不能直接使用实例成员,需要通过对象调用
public class TakeCare6 { public static void st() { System.out.println("static method"); TakeCare6 tc=new TakeCare6(); tc.test(); //test();//去掉注释后报错 Cannot make a static reference to the non-static method test() from the type TakeCare6 } public void test() { System.out.println("instance method"); } }
总结:static 修饰后的成员就像万能的 O 型血,在任何地方都能 类名.成员
调用(private
修饰除外),实例方法除了本类中的方法,只能 对象.成员
调用
搜索关注公众号「享智同行」,第一时间获取技术干货
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比
以下内容摘自我的 Gitchat :Java 程序员必备:并发知识系统总结,欢迎订阅! Github 地址:https://github.com/Snailclimb/JavaGuide/edit/master/Java相关/synchronized.md synchronized关键字最主要的三种使用方式的总结 修饰实例方法,作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁 。也就是给当前类加锁,会作用于类的所有对象实例,因为静态成员不属于任何一个实例对象,是类成员( static 表明这是该类的一个静态资源,不管new了多少个对象,只有一份,所以对该类的所有对象都加了锁)。所以如果一个线程A调用一个实例对象的非静态 synchronized 方法,而线程B需要调用这个实例对象所属类的静态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态 synchronized 方法占用的锁是当前实例对象锁。 修饰代码块,指定...
- 下一篇
DUBBO服务启动过程
Dubbo的启动主要是发布服务的过程,起到核心作用的就是ServiceConfig(ServiceConfig就是我们在Dubbo的配置文件中配置的dubbo:service这些配置项对应的实体类)。服务的启动初始位置也基本是在这里,下面我们来看看具体的实现内容。 讲基本内容前首先理清楚几个名词概念: Invoker:Invoker的概念我们在动态代理的时候就接触过,中文的意思大概是执行者,这里其实可以理解为具体方法的执行者。其核心内容大致如下: Class getInterface();Result invoke(Invocation invocation) throws RpcException;URL getUrl();通过以上的三个方法们就可以执行到具体的方法并且获得方法的执行结果。通过getUrl获得需要执行的方法具体实现细节,主要是获得具体的ref;其次就是组装方法的参数信息等等,这些信息在invocation里面都有封装;最后通过执行invoke方法触发具体的方法并返回结果。从这里可以看出Invoker是具体方法执行的最后一个守关者,获得了Invoker,就获得了具体接口...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- Red5直播服务器,属于Java语言的直播服务器
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS6,7,8上安装Nginx,支持https2.0的开启