配置Java环境
linweidadeMacBook-Pro:~ linweida$ javac
用法: javac <options> <source files>
其中, 可能的选项包括:
-g 生成所有调试信息
-g:none 不生成任何调试信息
-g:{lines,vars,source} 只生成某些调试信息
-nowarn 不生成任何警告
-verbose 输出有关编译器正在执行的操作的消息
-deprecation 输出使用已过时的 API 的源位置
-classpath <路径> 指定查找用户类文件和注释处理程序的位置
-cp <路径> 指定查找用户类文件和注释处理程序的位置
-sourcepath <路径> 指定查找输入源文件的位置
-bootclasspath <路径> 覆盖引导类文件的位置
-extdirs <目录> 覆盖所安装扩展的位置
-endorseddirs <目录> 覆盖签名的标准路径的位置
-proc:{none,only} 控制是否执行注释处理和/或编译。
-processor <class1>[,<class2>,<class3>...] 要运行的注释处理程序的名称; 绕过默认的搜索进程
-processorpath <路径> 指定查找注释处理程序的位置
-parameters 生成元数据以用于方法参数的反射
-d <目录> 指定放置生成的类文件的位置
-s <目录> 指定放置生成的源文件的位置
-h <目录> 指定放置生成的本机标头文件的位置
-implicit:{none,class} 指定是否为隐式引用文件生成类文件
-encoding <编码> 指定源文件使用的字符编码
-source <发行版> 提供与指定发行版的源兼容性
-target <发行版> 生成特定 VM 版本的类文件
-profile <配置文件> 请确保使用的 API 在指定的配置文件中可用
-version 版本信息
-help 输出标准选项的提要
-A关键字[=值] 传递给注释处理程序的选项
-X 输出非标准选项的提要
-J<标记> 直接将 <标记> 传递给运行时系统
-Werror 出现警告时终止编译
@<文件名> 从文件读取选项和文件名
如果打印出Javac后有上述内容,证明已经成功配置环境。
Public class 类名称 {} 和 class 类名称 {} 的区别 ?
Java程序分为两个操作:(1)编译程序:“javac 类名.java” ; (2)解释程序:“java 类名”
每个类只能有一个Public class类,但是可以由多个class类。如果类名与public class函数名不一致,运行“java 类名”的时候就会报错。
// 如果类名(public class Demo)与文件名(hello.java)不一致,则会产生以下错误
// linweidadeMacBook-Pro:Desktop linweida$ javac hello.java
// hello.java:1: 错误: 类Demo是公共的, 应在名为 Demo.java 的文件中声明
// public class Demo {
// ^
// 1 个错误
为什么要设置CLASSPATH?设置PATH和CLASSPATH
PATH是属于操作系统属性,定义所有可执行程序的路径。
CLASSPATH是属于Java程序解释类文件时所使用的加载路径。
当Java命令运行的时候实际上JVM会自动的找到CLASSPATH属性,而后找到此属性对应的内容,通过指定内容的路径来加载所需要的类。
CLASSPATH主要目的是定义类的加载路径,不管定义了多少个路径,一定要定义一个“.”(表示由当前所在目录进行类的加载)
Java方法
Java方法的格式:
public static 返回值类型 方法名称(参数类型 参数变量...) {
方法体(本方法要执行的若干内容)
return [返回值]
}
(1)定义一个没有参数没有返回值的方法:
public class Demo {
public static void main(String args[]){
// 调用方法
NO_PARAMETER_NO_RETURN(); // "无参无返回值"
HAS_PARAMETER_NO_RETURN(10.0); // "支付成功"
HAS_PARAMETER_NO_RETURN(0); // "尚未支付"
int result = HAS_PARAMETER_HAS_RETURN(10,20);
Ssystem.out.println("计算结果:" + result); // "计算结果:30"
Ssystem.out.println("计算结果:" + HAS_PARAMETER_HAS_RETURN(30,40)); // "计算结果:70"
HAS_RETURN_IN_MIDDLE(1); // "这是一个非零的数字"
HAS_RETURN_IN_MIDDLE(0); // 被return掉没有任何输出
}
// 定义没有参数,没有返回值的方法
public static void NO_PARAMETER_NO_RETURN(){
System.out.println("无参无返回值");
}
// 定义有参数没有返回值的方法
public static void HAS_PARAMETER_NO_RETURN(double money){
if(money > 0.0){
System.out.println("支付成功");
} else {
System.out.println("尚未支付");
}
}
// 定义有参数有返回值的方法
public static int HAS_PARAMETER_HAS_RETURN(int x, int y){
return x + y;
}
// return可以结束一个方法
public static void HAS_RETURN_IN_MIDDLE(int x){
if (x == 0) return;
System.out.println("这是一个非零的数字");
}
}
Java方法的重载,如果由一个方法名称,有可能要执行多项操作。
public class Demo {
public static void main (String args[]){
// 方法重载之后执行时会根据我们传入参数的类型或个数的不同调用不同的方法体
System.out.println("两个整型参数:"+add(10,20));
System.out.println("两个浮点型参数:"+add(10.1,20.9));
System.out.println("三个整型参数:"+add(10,20,30));
}
// add()方法一共被重载了三次
public static int add (int x , int y){
return x + y;
}
public static int add (int x , int y , int z){
return x + y + z;
}
public static double add (double x , double y){
return x + y;
}
// 注意:下面此方法不属于方法重载,由于参数类型和个数完全相同,视为上面同样的方法已存在
public static double add (int x , int y){
return x + y;
}
}
// 其实System.out.println 就是典型的被重载后的方法,无论什么数据类型凡在该方法里面都可以被输出。
// 方法重载有两点说明:
// (1)在进行方法重载时,一定要考虑参数类型的一致,但是从标准开发来讲,重载后的方法使用同一种返回值类型。
// (2)方法重载的时候重点是根据参数类型及参数个数来区分不同的方法,而不是依赖返回值的不同来确定的。
Java方法的递归调用,是迈向数据结构开发的第一步。
在标准的开发项目里面,是很难出现递归操作的。所谓的递归调用就是一个方法自己调用自己的情况,前提是需要一个结束的条件。并且每次调用的时候都需要修改结束条件。之所以在开发中尽量减少递归的调用,因为处理不当就会导致内存溢出。
实现一个1~100的递归操作
public class Demo {
public static void main (String args[]){
sum(50);
}
public static int sum(int caculator) {
int sum = 0;
int current = 1;
while (current <= caculator) {
sum += current;
currrent++;
}
System.out.println(sum);
}
public static recursion(int caculator) {
if (caculator == 1) return 1;
return caculator + sum(caculator - 1);
}
}
类与对象
// 如果方法不是在主类定义的,不需要加public static
// 在这个类中定义两个属性和一个方法
class Book {
String title; // 书的名字
double price; // 书的价格
public void bookDesc(String stirng) { // 书的描述
System.out.println("图书的名称:" + title + "图书的价格:" + price);
}
}
public class Demo {
public static void main (String args[]){
// 调用类时必须要有对象,对象属于引用数据类型。
// 对象的定义格式有两种:
// 声明并实例化对象:类名称 对象名称 = new 类名称();
// 分步完成:
// (1)声明对象(类名称 对象名称 = null)
// (2)实例化对象(对象名称 = new 类名称())
// 引用数据类型和基本数据类型,需要开辟及使用内存。所以关键字new的作用就是开辟内存空间。
// 在主类中声明Book对象,为其开辟内存空间
Book book = new Book();
// 对象.属性 表示操作类中的属性内容
// 对象.方法() 表示操作类中的方法
book.title = "linweida's book";
book.price = 999.9;
book.bookDesc() // 调用类中的方法
}
}
// 以上内存分析首先给出两块概念:
// 堆内存:保存每一个对象的属性内容,堆内存需要用关键字new来才可以开辟。
// 栈内存:保存的是一块堆内存的地址,但是为了分析方便,可以简单理解栈内存保存的是对象名字(其实是一块地址)。
// 当然所有的属性内存都是其对应数据类型的默认值。
// 垃圾空间指的是没有任何栈内存指向的堆内存空间,(也就是一块没有任何栈内存指向的堆内存空间就将成为垃圾),会被GC(垃圾收集器)不定时的回收,回收之后会释放掉其所占用的空间。
// 虽然Java里面支持了自动垃圾收集处理,但是代码开发过程中应当减少垃圾空间的产生。
Java构造方法与匿名方法
①类名称 ②对象名称 = ③new ④类名称();
①类名称:规定了对象的类型,即:对象可以使用哪些属性与哪些方法
②对象名称:如果要想使用对象,需要由一个名称,这是一个唯一的
③new:开辟新的堆内存空间,如果没有此语句,对象无法实例化
④类名称():调用一个和类名称一样的方法,这就是构造方法。
// 所有构造方法实际上一直被我们调用,但是从来没有定义过一个构造方法。之所以能够使用是因为在整个Java类之中,为了保证程序可以正常的执行,那么即使用户没有定义过任何的构造方法,也会在我们程序中自动的构建一个没有参数,方法名称与类名称相同,没有返回值的构造方法。这个就是他的要求。
构造方法的定义原则:方法名称与类名臣过的相同,没有返回值声明。
class Book {
public Book(){} // 无参的,无返回值的构造方法
}
如果在Book类里面没有写上以上的构造方法,那么就会自动生成一个。构造方法一直都存在,但是并没有发现构造方法有什么样的作用
class Book {
public Book(){
System.out.println("******");
}
public Book (String t){
System.out.println("对上面Book类,由一个参数的构造");
}
public Book (String t,double p){
System.out.println("对上面Book类,由两个参数的构造");
}
}
public class Demo {
public static void main(String args[]){
Book book = null; // 声明对象
book = new Book(); // 实例化对象
System.out.println(book);
book.print();
// book = new Book(); // 实例化对象
}
}
通过以上的代码可以发现,所有的构造方法都在对象使用关键字new实例化。构造方法与普通方法的最大区别:构造方法是在实例化只调用一次。普通方法是在实例化对象产生之后可以随意调用多次。既然构造方法是在对象实例化的时候使用的,那么请问,这样的做法有什么作用呢?
class Book { //
private String title;
private double price;
// 已经明确定义了一个构造方法,默认的构造方法将不再自动生成
public Book (String t,double p){
title = t;
// price = p;
setPrice(p); // 调用本类中的setter方法
}
public void setTitle(String t){
title = t;
}
public void setPrice(double p){
if(p > 0.0){
price = p;
}
}
// getter 不使用也得提供getter方法
public String getTitle(){
return title;
}
public String getPrice(){
return price;
}
public String getInfo(){
System.out.println("图书名称:"+title+price);
}
}
public class TestDemo {
public static void main(String args[]){
// 在实例化对象的同时将所需要的类属性传递到对象的构造方法里
Book book = new Book("Java开发",89.9); //
book.getInfo();
// 上面一句转换为“匿名对象”,作用于上述的作用作用。由于没有没有其它对象对其进行引用(Book book),所以只能使用一次,一次之后该对象空间将称为垃圾被等待回收。疑问?什么时候使用匿名对象?什么时候使用有名对象?答案,如果觉得匿名对象麻烦,就都用有名的。
new Book("Java开发",89.9).getInfo();
}
}
// 构造方法的核心作用:在类对象的实例化的时候设置属性的初始化内容,在类对象实例化的时候设置属性化准备的。一个类之中至少保留有一个构造方法。
// 如果一个类之中已经明确的定义了一个构造方法的话,那么自动生成的无参的,那么将不会再自动生成默认的构造方法。即一个类中至少保留有一个构造方法。
// 另外,既然构造方法也属于方法行列(),可以针对于构造方法进行重载,但是构造方法由于其定义的特殊性,所以在构造方法重载时,要求只注意参数的类型和个数即可。
// 在进行构造方法重载的时候有代码要求,请按照参数的个数进行升序排序。例如,先写没有参数的函数,再写有一个参数的函数,继续写两个参数的函数
// 遗留问题:在定义一个类的时候可以为属性直接设置默认值,但是这个默认值只有在构造执行完后才会设置,否则不会设置。而构造方法是属于整个对象构造过程的最后一步,即:留给用户处理的步骤。
// 在对象实例化过程之中一定会经历类的加载、内存的分配、默认值的设置、构造方法。构造方法是在最后一步调用的。
class Book {
private String title = "Java 开发";
public Book{} // title 现在的默认值跟次构造方法没关系
}
// 本程序之中只有在整个构造都完成之后,才会真正将“java 开发”这个字符串的内容设置给title属性。之前(再没有构造之前)title都是其对应数据类型的默认值。
// 既然有了构造方法的概念,实际上就可以照此方法使用匿名对象,之前定义的都属于有名对象(所有的对象都给了一个名字),但是这个名字真正使用的时候调用的是堆内存空间,即:真实的对象信息都保存在了堆内存空间之中,那么如果没有栈指向的对象就成为匿名对象。
总结
1、构造方法的定义要求:方法名称与类名称相同,无返回值;
2、构造方法是在类对象使用关键字new实例化的时候被默认使用,只要有了关键字new使用就一定需要构造方法。
3、一个类之中至少保留有一个构造方法。如果没哟明确定义构造方法,那么会自动地生成一个无参的什么都不做的构造方法;
4、构造方法的核心功能是在类对象实例化的时候为类中的属性初始化;
5、构造方法重载时只要求考虑参数的类型及个数即可;
6、匿名对象只能够使用一次
// 第一个代码模型:现在要求开发一个雇员的累,里面包含有雇员的编号、姓名、职位、基本工资、佣金。(这种功能的类在开发之间称为简单Java类,因为这些类里面不会包含有过于复杂的程序逻辑)
// 第一种开发要求:
// (1)类名称必须存在有意义,例如:Book,Employee
// (2)类之中所有的属性必须private封装,封装后的属性必须提供有setter、getter
// (3)类之中可以提供任意多个构造方法,但是必须保留由一个无参数的构造方法;
// (4)类之中不允许出现任何的输出语句,所有的信息输出必须交给被调用输出。
// (5)类之中需要提供一个取得对象完整信息的方法,暂定为getInfo(); 返回String型数据
class Employee {
private int emp_number;
private String emp_name;
private String emp_job;
private double emp_payment;
private double emp_commision;
// 重载方法
public Employee(){}
public Employee(int number, String name, String job , double payment , double commision){
emp_number = number;
emp_name = name;
emp_job = job;
emp_payment = payment;
emp_commision = commision;
}
// setter 设值方法
public void setEmp_number(int num){
emp_number = num;
}
public void setEmp_name(String name){
emp_name = name;
}
public void setEmp_job(String job){
emp_job = job;
}
public void setEmp_payment(double payment){
emp_payment = payment;
}
public void setEmp_commision(double commision){
emp_commision = commision;
}
// getter 取值方法
public int getEmp_number {
return num;
}
public String getEmp_name {
return name;
}
public String getEmp_job{
return job;
}
public double getEmp_payment {
return payment;
}
public double getEmp_commision {
return commision;
}
public String getInfo(){
return "雇员编号:"+ emp_number + "\n" + "雇员名字" + emp_name + "\n" + "职位" + emp_job + "\n" + "基本工资" + emp_payment "\n" + + "佣金" + emp_commision;
}
public static void main(String args[]){
}
}
// 测试程序
public class TestDemo {
public static void main(String args[]){
Employee emp = new Employee(0001,"linweida","CLERK",100.0,1000.0);
System.out.println(emp.getInfo());
// 通过setter方法修改上面emp对象的name值
emp.setEmp_name = "hero";
// 单独使用getter方法调用内容
System.out.println("姓名:"+emp.getEmp_name());
}
}
// 所有类之中提供的setter、getter方法可能谋学操作不会使用到,但是依然必须。同时所有setter方法除了具备有设置修改属性内容之外,也具备有修改属性内容的功能。