今天分享一些有关Java方法的基本应用规则及其原理。不过要事先声明一下,今天的笔记中关于Java传参原理 的这部分内容理解起来有些许的难度,感兴趣的朋友可以作为提高内容进行学习。(我把参考视频的链接放了在文尾供参考。)
方法的参数
体会可变个数的形参
-
采用数组 + for循环形式传递可变个数的形参
-
声明方式:public static void test( int a ,String[] books);
public class Person2 { public void printInfo(String[] args) { //数组 for(int i=0; i<args.length; i++) { //for循环 System.out.println(args[i]); }}}/**调用Persona2类定义的方法*/public class Test_Person2 { public static void main(String[] args) { String[] ss = new String[] {"姓名:张三","性别:男","身份证号码:411402198512166438","联系方式:15932158669"}; Person2 p = new Person2(); // 声明一个Person类的对象——p; p.printInfo(ss); // 对象p调用person类的方法——printInfo; String[] tt = new String[] {"姓名:王欣","性别:女","身份证号码:411402199910105237","联系方式:13465203200","毕业学校:北京工业大学","主修专业:计算机科学与技术"}; p.printInfo(tt);}}
-
采用Java特有的 … 传递可变个数的形参
-
声明方式:public static void test( int a ,String…books);
-
声明方式:方法名(参数的类型名…参数名)
-
方法的参数部分有可变形参,需要放在形参声明的最后
-
public static void test(String s,int a,String…books); // String…books必须放到最后
-
public class Test_Person2 { public static void main(String[] args) { Person2 p = new Person2(); // 声明一个Person类的对象——p; p.printInfo2("姓名:张三","性别:男","身份证号码:411402198512166438","联系方式:15932158669"); String[] aa = new String[] {"姓名:王欣","性别:女","身份证号码:411402199910105237","联系方式:13465203200"}; p.printInfo2(aa); //由5~8行代码可见:在Java特有的 ... 方式中,直接传递数据与将数据放入数组中在从传递数据的效果是一模一样的 p.printInfo1(null); // 用'数组的方式'来传递可变个数的参数,如果没有参数,就要定义一个空数组或者是null p.printInfo2(); // 用java特有的...的方式来传递可变个数的参数,这种参数在使用时与数组的使用方式相同,如果没有参数就可以不填。}}
方法的参数传递
-
方法只有被调用才有意义。若方法含有参数:
-
实参:方法声明时的参数。
-
形参:方法调用时实际传给形参的参数值。
-
-
Java的实参值如何传入方法呢?
-
Java里方法的参数传递方式只有一种:值传递。
-
即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。
-
-
在学习方法的参数传递前,我们先要通过一块代码了解JVM内存模型的工作原理:
int i = 1;Person = new Person();
-
基本数据类型传参:
-
基本数据类型在参数传递的过程中,就是把实参的值复制一份给形参。
-
基本数据类型都是保存在栈内存中。
-
public class TestTransfer { public static void swap(int i) { i = 6; System.out.println("swap方法里i的值是:" + i);} public static void main(String[] args) { int a = 0; swap(a); System.out.println("main方法里a的值是:" + a);}}
-
引用对象传参:
public class DataSwap{ public int a;}public class TestTransfer1 { public static void Swap(DataSwap ds1) { ds1.a = 6; System.out.println("Swap方法里,a的值是:" + ds1.a); // a的值为:6} public static void main(String[] args) { DataSwap ds2 = DataSwap(); // ?? System.out.println("在执行swap前main方法里a的值是:" + ds2.a); // a的值为:0 Swap(ds2); System.out.println("在执行swap后main方法里a的值是:" + ds2.a); // a的值为:6}}
-
方法的参数传递总结:
-
如果方法的形参是基本数据类型,那么实参(实际的数据) 向形参传递参数时,就是直接传递值,把实参的值复制给形参。
-
如果方法的形参是对象,那么实参(实际的对象) ,向形参传递参数时,也就是把值给形参,这个值是实参在栈内存中的值,也就是引用对象在堆内存中的地址。
-
基本数据类型都是保存在栈内存中;引用对象在栈内存中保存的是引用对象的地址,那么方法的参数传递是传递值(是变量在栈内存当中的值)
封装和隐藏
-
先把属性设置成私有的,格式为:private 关键字
-
通过编写public类型的setXxx() 和 getXxx() 方法来设置属性和获取属性,比如对age去写get和set方法,那么方法名就是:setAge(),getAge()
/**封装*/public class Person { private int age; // 1.把属性设置成私有的,格式为:private 关键字} public void getAge(int a) { // 2.编写public类型的setXxx() 和 getXxx() 方法来设置属性和获取属性 if(a>0 && a<150) { age = a; }else { System.out.println("输入的年龄:" + a +",不在0~150之间"); }}}
public class Test { public static void main(String[] args) { Person p = new Person();// p.age = -100; // 使用了private int age;后,对象p就不能直接访问到age属性了 p.getAge(-40); p.printAge();}}
-
为什么要进行封装?
-
使用者对类内部定义的属性(对象的成员变量)的直接操作会可能会导致数据的错误、混乱或安全性问题。
-
-
封装的目的:
-
隐藏一个类中不需要对外提供的实现细节
-
使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作
-
便于修改,增强代码的可维护性
四种访问权限修饰符
修饰符 | 类内部 | 同一个包 | 子类 | 所有地方 |
---|---|---|---|---|
private | Yes | |||
default(缺省) | Yes | Yes | ||
protected | Yes | Yes | Yes | |
public | Yes | Yes | Yes | Yes |
-
对于class的权限修饰只可以使用 public 和 default(缺省) 。
-
public类可以在任意地方被访问。
-
default类只可以被同一个包内部的类访问。
-
类的成员之三——构造器(构造方法)
new对象实际上就是调用类的构造方法
构造器的作用:创建对象;给对象进行初始化
-
如:Order o = new Order(); Person p = new Person(Peter,15);
-
如同我们规定每个“人”一出生就必须先洗澡,我们就可以在“人”的构造方法中加入完成“洗澡”的程序代码,于是每个“人”一出生就会自动完成“洗澡”,程序就不必再在每个人刚出生时一个一个地告诉他们要“洗澡”了。
语法格式:
修饰符 类名 (参数列表) { 初始化语句;}
public class Person { public Person() { // 构造器的名称必须与类的名称相同; age = 22; // 创建的任何Person类的对象,其age属性的初始值都是22; } int age;}public class Test { public static void main(String[] args) { Person p = new Person(); //调用构造器,创建People类的实例,将age初始化为22; }}
构造器特征:
-
它具有与类相同的名称
-
它不声明返回值类型。(与声明为void不同)
-
不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
-
如果不专门设置构造器,在创建类的时候系统会自动默认有一个构造器。所以我们一般在 “ new 对象 ” 的时候可以不用单独写一个构造器,直接 “类名 对象名 = new 类名 ”创建一个新的对象。
注 意:
-
Java语言中,每个类都至少有一个构造器
-
默认构造器的修饰符与所属类的修饰符一致
-
一旦显式定义了构造器,则系统不再提供默认构造器
-
一个类可以创建多个重载的构造器
-
父类的构造器不可被子类继承
构造器的重载
构造器也叫构造方法,既然是方法,就可以重载。
构造器重载的意义:构造器的重载,就是为了方便调用方可以灵活的创建出不同需要的对象。重载的多个构造方法实际上就是相当于提供了多个初始化new对象的模板。
public Person6(){}public Person6(int a){}public Person6(String n){}public Person6(int a String n){}
JavaBean
所谓javaBean,是指符合如下标准的Java类:
-
类是公共的
-
有一个无参的公共的构造器
-
有属性,属性一般是私有的,且有对应的get、set方法
package 构造器练习;/** * 一个JavaBean * 私有的属性 * 属性对应的get和set方法 * @author Lenovo * */public class Person2 { private String name; private int age; private String sex; // 写好属性后,鼠标右键-->Source-->Generate Getter and Setters,第14~31行的getXxx()与setXxx()方法会自动写好。 public String getName() { return name;} public void setName(String name) { this.name = name;} public int getAge() { return age;} public void setAge(int age) { this.age = age;} public String getSex() { return sex;} public void setSex(String sex) { this.sex = sex;}}
参考视频:方法的参数传递原理