new Date(); //该表达式构造了一个新对象,这个对象被初始化为当前的日期和时间
String s=new Date().toString(); //Date类有一个toStrng方法,这个方法将返回日期的字符串描述
上面两个例子中,构造的对象仅使用了一次。要想构造的对象可以多次使用,需要将对象存放在一个变量中
Date birthday=new Date(); //对象变量 birthday,它引用了新构造的对象
对象变量并没有实际包含一个对象,它只是引用一个对象。Java中,任何对象变量都是对存储在另外一个地方的某个对象的引用。
Java类库中的 LocalDate类
LocalDate类,用大家熟悉的日历表示法表示日期
不要使用构造器来构造 LocalDate类的对象。应当使用静态工厂方法(factory method),它会代表调用构造器
LocalDate.now(); //会构造一个新对象,表示构造这个对象时的日期
LocalDate.of(1999.12.31); //可以提供年、月和日来构造对于的一个特定日期的对象
LocalDate newYearsEve=LocalDate.of(1999,12,31); //将构造的对象保存在一个对象变量中
plusDays方法会得到一个新的 LocalDate,这个新日期对象则是距应用这个方法的对象指定天数的一个新日期
LocalDate aThousandDaysLater=newYearEve.plusDays(1000); //plusDays方法会生成一个新的 LocalDate对象,然后把这个新对象
赋给aThousandDaysLater变量。原来的对象不做任何改动
int year=aThousandDaysLater.getYear(); //方法 getYear得到年。结果,2002
int month=aThousandDaysLater.getMonthValue(); //方法 getMonthValue得到月。结果,09
int day=aThousandDaysLater.getDayOfMonth(); //方法 getDayOfMonth得到日。结果,26
Java较早版本增加有另一个处理日历的类,GregorianCalendar
GregorianCalendar someDay=new GregorianCalendar(1999, 11, 31); //与 LocalDate.plusDays方法不同,GregorianCalendar.add方法
someDay.add(Calendar.DAY_OF_MONTH, 1000); 是一个更改器方法。调用这个方法后,someDay对象的状态会改变
int year=someDay.get(Calendar.YEAR); //2002
int month=someDay.get(Calendar.MONTH)+1; //09
int day=someDay.get(Calendar.DAY_OF_MONTH); //26
用户自定义类
带有 public访问修饰符的EmployeeTest类源文件中包含了一个Employee非公共类
在一个源文件中,只能有一个公共类,但可以有任意数目的非公共类
Employee[] staff=new Employee[3]; //构造一个 Employee数组,并填入3个Employee对象 staff[0]=new Employee("Carl Cracker",75000,1987,12,15); staff[1]=new Employee("Harry Hacker",50000,1989,10,1); staff[2]=new Employee("Tony Tester",40000,1990,3,15);
for(Employee e:staff) //使用Employee类的raiseSalary方法将每个员工的薪水提高 5%
e.raiseSalary(5);
for(Employee e:staff) //调用 getName方法、getSalary方法和getHireDay方法打印各个员工的信息
System.out.println("name="+e.getName()+",salary="+e.getSalary()+",hireDay="+e.getHireDay());
剖析 Employee类
public Employee(String n,double s,int year,int month,int day) //这个类的所有方法都被标记为 public ,关键字public意味着任何类
public String getName() 的任何方法都可以调用这些方法
public double getSalary()
public LocalDate getHireDay()
public void raiseSalary(double byPercent)
在 Employee类中有3个实例字段用来存放将要操作的数据
private String name; //关键字 private确保只有 Employee类自身的方法能够访问这些实例字段,而其他类的方法
private double salary; 不能够读写这些字段
private LocalDate hirDay;
有两个实例字段本身就是对象:name字段是 String类对象,hireDay字段是LocalDate类对象。(类包含的实例字段通常属于某个类类型)
从构造器开始
Employee类的构造器
public Employee(String n,double s,int year,int month,int day) { //构造器与类同名。在构造 Employee对象时,构造器会允许,
name=n; 从而将实例字段初始化为所希望的初始状态
salary=s;
hirDay=LocalDate.of(year,month,day);
}
例如,当使用下面这条代码创建 Employee类的实例时:
new Employee("James Bond",100000,1950,1,1); //构造器与其他方法有一个重要的不同。构造器总是结合new操作符来调用
将会把字段设置为:
name="James Bond";
salary=100000;
hireDay=LocalDate.of(1950,1,1);
有关构造器总结
构造器与类同名
每个类可以有一个以上的构造器
构造器可以有0个、1个或多个参数
构造器没有返回值
构造器总是伴随着new操作符一起调用
用 var 声明局部变量
在 Java10中,如果可以从变量的初始值推导出它们的类型,就可以用 var关键字声明局部变量,而无需指定类型。
var harry=new Employee("Harry Hacker", 50000, 1989, 10, 1); //替代 Employee harry=new Employee("Harry Hacker", ...)
注意:不会对数值类型使用 var,如 int、long或 double,使你不用当心 0、0L和 0.0之间的区别。
var关键字只能用于方法中的局部变量,参数和字段的类型必须声明。
使用 null 引用
一个对象变量包含一个对象的引用,或者包含一个特殊值null,后者表示没有引用任何对象。要小心使用 null值
LocalDate birthday=null; //如果对 null值应用一个方法,会产生一个 NullPointerException异常
String s=birthday.toString(); //NullPointerException
我们不希望 name或 hireDay字段为 null(不用担心 salary字段,这个字段是基本类型,所以不可能是 null)
隐式参数与显示参数
方法用于操作对象以及存取它们的实例字段。例如,以下方法
public void raiseSalary(double byPercent) {
double raise=salary*byPercent/100;
salary+=raise;
}
将调用这个方法的对象的salary实例字段设置为一个新值。考虑下面这个调用
number007.reiseSalary(5);
它的结果是将 number007.salary字段的值增加5%。具体地说,这个调用将执行下列指令:
double raise=number007.salary * 5 / 100;
number007.salary+=raise;
raiseSalary方法有两个参数。第一个参数称为隐式参数,是出现在方法名前的Employee类型的对象(number007)。第二个参数是位于方法名后 面括号中的数值,这是一个显式参数
在每一个方法中,关键字 this指示隐式参数。如下改写 raiseSalary方法:
public void raiseSalary(double byPercent) {
double raise=this.salary*byPercent/100;
this.salary+=raise;
}
封装的优点
public String getName() { //这些都是典型的访问器方法。
return name;
} 由于它们只返回实例字段值,因此又称为字段访问器
public double getSalary() {
return salary; //这样,name就是一个只读字段。一旦在构造器中设置,就没有任何办法可以对它进行修改
} 这样我们可以确保name字段不会受到外界的破坏
public LocalDate getHireDay() {
return hirDay;
}
想要获得或设置实例字段的值。需要下面三项内容
一个私有的数据字段 (例如,private String name)
一个公共的字段访问器方法 (例如,getName方法)
一个公共的字段更改器方法 (例如,setName方法)
私有方法
在 Java中,要实现私有方法,只需将关键字 public 改为 private 即可。
如果一个方法是公共的,就不能简单地将其删除,因为有可能会有其他代码依赖这个方法。
final 实例字段
这样的字段必z须在构造对象时初始化。(也就是说,确保每一个构造器执行后,该字段值已经设置,并且以后不会再修改这个字段)
class Employee{ //在对象构造后,这个值不会再改变,即没有 setName方法
private final String name; //final 修饰符对于类型为基本类型或者不可变类的字段尤其有用
} String 类就是不可变的。(类中所有方法都不会改变其对象)
class Employee{
private int id; //每一个 Employee对象都有一个自己的 id字段,但这个类的所有实例将共享一个 nextId字段
private static int nextId=1; //即使没有 Employee对象,静态字段 nextId也存在,它属于类,而不属于任何单个的对象
}
静态常量
静态变量使用得比较少,但静态常量却很常用。例如,在 Math类中定义一个静态常量:
public class Math{ //在这个程序中,可以用 Math.PI来访问这个常量
public static final doule PI=3.1415926535; //如果省略了关键字 static,PI就变成了Math类的一个实例字段。也就需要通过
} Math类的一个对象来访问 PI,并且每个Math对象都有它自己的一个 PI副本
静态方法
静态方法是不在对象上执行的方法。例如,Math类的 pow方法就是一个静态方法。表达式 Math.pow(x,a) 幂运算
Employee类的静态方法不能访问 id实例字段,因为它不能在对象上执行操作,只可以访问静态字段
public static int getNextId() { //可以提供类名来调用这个方法:int n=Employee.getNextId();
return nextId;
}
在下面两种情况下可以使用静态方法:
方法不需要访问对象状态。(对象状态的改变必须通过调用方法实现)
方法只需要访问类的静态字段(例如,Employee.getNextId)
工厂方法
静态方法的另外一种常见的用途。类似 LocalDate和 NumberFormat的类使用静态工厂方法来构造对象
NumberFormat currencyFormatter=NumberFormat.getCurrencyInstance(); //NumberFormat类如下生成不同风格的格式化对象
NumberFormat percentFormatter=NumberFormat.getPercentInstance(); //NumberFormat类不利用构造器完成这些操作的原因:
double x=0.1; 1.无法命名构造器。构造器名字必须与类名相同。这里希望有两个不同的名字
System.out.println(currencyFormatter.format(x)); 2.使用构造器时,无法改变构造对象的类型。而工厂方法实际上将返回
System.out.println(percentFormatter.format(x)); DecimalFormat类的对象
main方法
main也是一个静态方法。不对任何对象进行操作。在启动程序时还没有任何对象。静态的main方法将执行并构造程序所需要的对象
方法参数
按值调用表示方法接收的是调用者提供的值。按引用调用表示方法接收的是调用者提供的变量地址。
方法可以修改按引用传递的变量的值,而不能修改按值传递的变量的值。
Java程序设计语言总是按值调用。方法不能修改传递给它的任何参数变量的内容。例如,下面的调用:
double percent=10; harry.raiseSalary(percent); //该方法调用后,percent的值还是10
一个方法不可能修改基本数据类型的参数,而对象引用作为参数就不同了。例如,下面:
public static void tripleSalary(Employee x){ //将一个员工的工资增至三倍
x.raiseSalary(200); //1.x初始化为harry值的一个副本,这里就是一个对象引用
}
当调用
harry=new Employee(...); //2.raiseSalary方法应用于这个对象引用。x和harry同时引用的那个Employee对象的工资提高了200%
tripleSalary(harry); //3.方法结束后,参数变量x不再使用。对象变量harry继续引用那个工资增至3倍的员工对象
总结:在Java中对方法参数能做什么和不能做什么
方法不能修改基本数据类型的参数(即数值型或布尔型)
方法可以改变对象参数的状态。(对象状态的改变必须通过调用方法实现)
原文:https://www.cnblogs.com/changming22/p/13448507.html