public static void main (String[] args) 详解
public static void main (String[] args) 是Java程序的入口方法,JVM在运行程序时,会先查找 main() 方法。
public 是权限修饰符,表明任何类或对象都可以访问这个方法。
static 表明mian()方法是一个静态方法,即方法中的代码是存储在静态存储区的,只要类被加载后,就可以使用该方法而不需要通过实例化对象来访问,可以直接通过类名.main() 直接访问。
void 表明方法没有返回值。
main 是JVM识别的特殊方法名,是程序的入口方法。
字符串数组参数args 为开发人员在命令行状态下与程序交互提供了一种手段。
引申:
(1)main() 方法是否还有其他可用的定义格式?
static public void main (String[] args) —— public 和 static 没有先后顺序
public static final void main (String[] args) —— 可以定义为final
public static synchronized void main (String[] args) —— 可以上同步锁
不管用哪种定义方式,都必须保证 main() 方法的返回值为 void,并有 static 和 public 关键字修饰。同时由于 main() 方法为程序的入口方法,因此不能用 abstract 关键字来修饰。
(2)同一个 .java 文件中是否可以有多个 main() 方法?
虽然每个类中都可以定义 main() 方法,但是只有与文件名相同的用 public 修饰的类中的 main() 方法才能作为整个程序的入口方法。
class T {
public static void main (String[] args) {
System.out.println("T main");
}
}
// 必须是用 public 修饰,且类名与文件名相同的类中的 main() 方法才是入口。
public class Test {
public static void main (String[] args) {
System.out.println("Test main");
}
}
程序运行结果为:
Test main
方法:
Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段
public class Demo {
float a;
//实例方法
void sum(float num1,float num2){
a = Max(num1,num2);
} //类方法
static float Max(float num1,float num2){
//取最大值
return num1 <= num2 ? num2 :num1;
} public static void main(String[] args) {
Demo demo =new Demo();
demo.sum(22,33); //实例方法必需先初始化类的实例,然后通过类的实例才能调用
Demo.Max(12,9); // 类方法可以直接通过类名调用 }
}
- 一个类中的方法可以互相调用。但要注意:实例方法可以调用该类中的其他方法,例如,sum()可以调用Max()。类方法只能调用其他类方法,不能调用实例方法。
- 类方法又叫静态方法, 实例方法又叫非静态方法。
- 类方法可以直接通过类名调用,实例方法必需先初始化类的实例,然后通过类的实例才能调用
JAVA中的父类与子类
在java中,一个父类可以有多个子类,但是子类只能有一个父类。子类通常通过关键字extends来继承父类。
public class Animal {
int a = 3;
AnimalClass() {
System.out.println("父类无参构造函数");
}
AnimalClass(int i) {
System.out.println("有一个形参i");
}
AnimalClass(int i,int j){
System.out.println("有两个形参i,j");
}
}
class DogClass extends AnimalClass {
int a;
int b;
public DogClass() {
System.out.println("123一起上");
}
public class DogClass(int a) {
this a = a;
System.out.println("456一起上");
}
public AnimalClass() {
super.(3,4);
}
public show() {
System.out.println("show 好!");
}
public static void main(String[] args) {
DogClass sc1 = new Dogclass ();
AnimalClass sc2 = new Animalclass ();
AnimalClass sc3 = new Animalclass (3,4);
}
}
这就是一个简单的父类与子类
implements:
extends 是继承父类,只要那个类不是声明final或者定义为abstract就能继承,Java中不支持多重继承,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了。
class A extends B implements C,D,E(){ //class子类名extends父类名implements接口名
}
覆盖:
一、Java中的方法覆盖
1.方法覆盖又称为方法重写,英语单词:override/overwrite
2.使用:
当父类中的方法已经无法满足当前子类的业务需求,子类有必要将父类中继承过来的方法进行重新编写,这个重新编写的过程称为方法的重写/覆盖
3.满足的条件:
方法的重写发生在具有继承关系的父子类之间
方法名相同返回值类型相同,返回值列表相同(尽量复制粘贴)
访问权限不能更低,可以更高
抛出异常可以更多,可以更少。
4.注意:
私有方法不能继承,所以不能覆盖。
构造方法不能继承,所以不能覆盖。
静态方法不存在覆盖。
覆盖只针对方法,不谈属性。
public class OverrideTest {
public static void main(String[] args) {
Animal a=new Animal();
a.move();
Cat bCat=new Cat();
bCat.move();
Bird bird=new Bird();
bird.move();
}
} public class Animal {
public void move() {
System.out.println("动物在移动");
}
} public class Cat extends Animal{
public void move() {
System.out.println("猫在走猫步");
}
} public class Bird extends Animal{
public void move() {
System.out.println("鸟儿在飞翔");
}
}
java中覆盖和重载的区别
1. 首先搞明白覆盖是什么?
· 举个栗子
public class Main {
public static void main(String[] args) {
new Father().print();
new Son().print();
}
}
class Father{
public void print(){
System.out.println("father");
}
}
class Son extends Father{
@Override
public void print() {
System.out.println("SON");
}
}
·
2.重载是什么?
· 举个栗子
public class Main {
public static void main(String[] args) {
new Test().print();
new Test().print(3);
new Test().print(3,"双参");
}
}
class Test{
public void print(){
System.out.println("无参");
}
public void print(int i){
System.out.println(i+" "+"单参");
}
public void print(int i,String j){
System.out.println(i+" "+j);
}
}
该例子里写了多个print方法,但参数不同,因此可以运行,这也就是重载的含义,一个类中可以有多个同名不同参(参数列表不同)的方法。
final用法:
final关键字代表最终、不可改变的。 常见四种用法: 1. 可以用来修饰一个类 2. 可以用来修饰一个方法 3. 还可以用来修饰一个局部变量 4. 还可以用来修饰一个成员变量
接口:
接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法所组成。接口是解决Java无法使用多继承的一种手段,但是接口在实际中更多的作用是制定标准的。或者我们可以直接把接口理解为100%的抽象类,既接口中的方法必须全部是抽象方法
为什么要用接口
接口被用来描述一种抽象。
因为Java不像C++一样支持多继承,所以Java可以通过实现接口来弥补这个局限。
接口也被用来实现解耦。
接口被用来实现抽象,而抽象类也被用来实现抽象,为什么一定要用接口呢?接口和抽象类之间又有什么区别呢?原因是抽象类内部可能包含非final的变量,但是在接口中存在的变量一定是final,public,static的。
接口语法:
java类前使用 private static 类名 对象 = new 类名() 的作用。
举例:这里有一个DButils工具类,专门用来对数据库进行增,删,改,查“”操作。
public class DButils {
public void add() {
System.out.println("对数据库进行add操作");
} public void update() {
System.out.println("对数据库进行update操作");
} public void query() {
System.out.println("对数据库进行query操作");
}
public void delete() {
System.out.println("对数据库进行delete操作");
}
}
现在,在Service类中对DButils中的方法进行调用,
public class Service {
private DButils utils = new DButils(); public void methodA() {
utils.add();
utils.query();
} public void methodB() {
utils.update();
utils.add();
} public void methodC() {
utils.delete();
utils.add();
}
}
可以看出,在Service类中只创建了一个DButils对象,但却可以在下方的methodA,methodB,methodC方法中进行重多次的调用。
好处:
1、多次调用DButils中的方法,但只需要创建一次对象,因此,大大节省了创建对象所需的内存空间,并且方便调用【在开发中经常使用】
2、private表示私有,在同一类内可见, 因此在其他类中无法直接对该对象进行修改,保证了对象的安全性。
类:
package NeiBuLei;
public class OuterClass {
//成员变量
private String OuterName;
//成员方法
public void display(){
System.out.println("这是外部类方法!");
System.out.println(OuterName);
}
//内部类
public class InnerClass{
//成员变量
private String InnerNme;
//构造方法
public InnerClass() {
InnerNme = "Inner Class";
}
//成员方法
public void display(){
System.out.println("这是内部类方法!");
System.out.println(InnerNme);
}
}
// 主方法
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
outerClass.display();//这是外部类方法!null // 这个类是内部类,已经不是独立的类了,因此不能像外部类一样直接创建!
//InnerClass innerClass = new InnerClass(); 行不通
OuterClass.InnerClass innerClass = outerClass.new InnerClass();// 同成员方法/变量 只是加了个前缀
innerClass.display();// 这是内部类方法!
}
}
反射//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object
// 类型的对象,而我不知道你具体是什么类,用这种方法
Person p1 = new Person();
Class c1 = p1.getClass();//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
// 这说明任何一个类都有一个隐含的静态成员变量 class
Class c2 = Person.class;//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
// 但可能抛出 ClassNotFoundException 异常
Class c3 = Class.forName("com.ys.reflex.Person");
list方法和数组相比,list是动态的
map:
以键值对形式来保存数据 ---key ---value;
键(key)值(value)来保存数据,其中值(value)可以重复,但键(key)必须是唯一,相同就覆盖;
也可以为空,但最多只能有一个key为空;
它的主要实现类有HashMap(去重)、LinkedHashMap、TreeMap(排序)。 指的都是对key 的操作;
HashSet去重和HashMap的关系:
HashSet依赖Map 存储数据,set在保存数据时,实际上是在向Map中key这一列中存数据;
2、Map通用方法
put(key,value):存入Map中的一个key-value键值对映射;
get(key):返回指定key所映射的值;
int size():返回键值对的数量;
remove(key):删除指定key的一对映射;
containsKey(key):判断是否包含指定的key;
package com.zb.study.map;
import java.util.HashMap;
import java.util.Map;
//测试HashMap
public class TestHashMap {
public static void main(String[] args) {
//创建HashMap
Map<String,String> map = new HashMap<>();
//存放元素
map.put("齐天大圣","孙悟空");
//取出元素
String s = map.get("齐天大圣");
System.out.println(s);
//获取map长度
int size = map.size();
System.out.println(size);
//判断是否包含指定key
boolean b = map.containsKey("齐天大圣");
System.out.println(b);
}
}
Super
super 可以用来直接调用父类中的构造方法
1. public class Person {
2. public Person(String name, int age) {
3.
4. }
5.
6. public Person(String name, int age, String sex) {
7.
8. }
9. }
10. public class Student extends Person {
11. public Student(String name, int age, String birth) {
12. super(name, age); // 调用父类中含有2个参数的构造方法
13. }
14.
15. public Student(String name, int age, String sex, String birth) {
16. super(name, age, sex); // 调用父类中含有3个参数的构造方法
17. }
18. }
super和this的区别
this 指的是当前对象的引用,super 是当前对象的父对象的引用。下面先简单介绍一下 super 和 this 关键字的用法。
super 关键字的用法:
- super.父类属性名:调用父类中的属性
- super.父类方法名:调用父类中的方法
- super():调用父类的无参构造方法
- super(参数):调用父类的有参构造方法
如果构造方法的第一行代码不是 this() 和 super(),则系统会默认添加 super()。
this 关键字的用法:
- this.属性名:表示当前对象的属性
- this.方法名(参数):表示调用当前对象的方法
当局部变量和成员变量发生冲突时,使用this.
进行区分。
java Iterator(迭代器)
要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。
Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext() 用于检测集合中是否还有元素。
调用 it.remove() 将迭代器返回的元素删除。
Iterator 类位于 java.util 包中,使用前需要引入它,语法格式如下:
import java.util.Iterator; // 引入 Iterator 类
// 获取迭代器
Iterator<String> it = sites.iterator();
集合:
3.常用集合的分类:
Collection 接口的接口 对象的集合(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│—————-├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序
Map 接口 键值对的集合 (双列集合)
├———Hashtable 接口实现类, 同步, 线程安全
├———HashMap 接口实现类 ,没有同步, 线程不安全-
│—————–├ LinkedHashMap 双向链表和哈希表实现
│—————–└ WeakHashMap
├ ——–TreeMap 红黑树对所有的key进行排序
└———IdentifyHashMap
————————————————
Properties是HashTable的子类
不过Properties添加了两个方法,load()和store()可以直接导入或者将映射写入文件。另外Properties是<String,String>的映射。