Java 基础知识点汇总(含代码示例+图解)_java 知识点
Java基础笔记
文章目录
- Java基础笔记
-
- Java概述
-
- JVM、JRE和JDK
- Java常用的包
- java字节码
- Java标识
-
-
- Java标识符定义
- Java标识符规则
-
- Java和C++的区别
- 名词概念
- 面向对象概述
-
- 面向对象三大特性
- 2. 抽象类与接口
- 3. this和super关键字
- Java关键字
-
- switch case语句
- goto
- final
- final finally finalize区别
- this关键字的用法
- super关键字的用法
- this与super的区别
- static存在的主要意义
- 包装类相关
- 异常处理
-
- 1. 异常的分类
- 2. 异常处理机制(try-catch-finally)
- 3. 自定义异常
- IO流
-
- java 中 IO 流分类
- Files的常用方法
- Java常用类
-
- 1. 字符串操作
- 2. 集合框架
- 3. 日期与时间
- 多线程
-
- 1. 线程的创建与控制
- 2. 线程的同步与通信
-
- 线程同步
- 线程通信
- 3. 并发工具类
- java反射机制
-
- 反射概述
- 反射机制优缺点
- 反射机制的应用场景
- Java获取反射的三种方法
- 注解与元数据
-
- 1. 注解的定义与使用
- 2. 自定义注解
- 补充:
-
- Java数组的创建
- for each遍历
- public static void与public void的区别
- 补充:
-
- Java数组的创建
- for each遍历
- public static void与public void的区别
Java概述
JVM、JRE和JDK
-
JVM:
Java Virtual Machine
是Java虚拟机,Java程序需要运行在虚拟机上,不同的平台有自己的虚拟机,因此Java语言可以实现跨平台。 -
JRE:
Java Runtime Environment包
括Java虚拟机和Java程序所需的核心类库等。核心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包 -
JDK:
Java Development Kit
是提供给Java开发人员使用的,其中包含了Java的开发工具,也包括了JRE。所以安装了JDK,就无需再单独安装JRE了。其中的开发工具:编译工具(javac.exe),打包工具(jar.exe)等
[!CAUTION]
JVM&JRE&JDK关系图:
[!CAUTION]
Java 程序运行流程图:
[!NOTE]
C++程序运行流程:
Java常用的包
JDK 中常用的包有:
java.lang
:这个是系统的基础类;
java.io
:这里面是所有输入输出有关的类,比如文件操作等;
java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;
java.net:这里面是与网络有关的类;
java.util
:这个是系统辅助类,特别是集合类;
java.sql:这个是数据库操作的类。 javax.servlet:这个是JSP,Servlet等使用到的类。
java字节码
**字节码:**Java源代码经过虚拟机编译器编译后产生的文件(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机。
采用字节码的好处:
Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。
Java标识
Java标识符定义
- 包名、类名、方法名、参数名、变量名等,这些符号被称为标识符。
- 标识符可以由字母、数字、下划线_ 和 美元符号 $ 组成
- 标识符不能以数字开头,不能是java中的关键字。
- 首字符之后可以是字母(AZ 或者 az)、下划线_ 、美元符号 $ 或数字的任何字符。
- Java 区分大小写,因此 myvar 和 MyVar 是两个不同的标识符。
- 不可以使用关键字和保留字作为标识符,但标识符中能包含关键字和保留字。
- 标识符不能包含空格。
Java标识符规则
- 包名所有字母必须小写。例如:cn.com.test
- 类名和接口名每个单词的首字母都要大写。例如:ArrayList
- 常量名所有的字母都大写,单词之间用下划线连接。例如:DAY_OF_MONTH
- 变量名和方法名的第一个单词首字母小写,从第二个单词开始,每个单词首字母大写。例如:lineName、getLingNumber
- 在程序中,应该尽量使用有意义的英文单词来定义标识符,使得程序便于阅读。例如:使用userName表示用户名,password表示密码。
Java和C++的区别
- Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。
- 内存安全:Java有自动内存管理机制,且不提供指针来直接访问内存,程序内存更加安全
- 解释对编译:Java是一种解释性语言,需要JVM。而C++是编译语言
名词概念
1. JDK (Java Development Kit):Java开发工具包,包含Java编译器、Java类库、运行时环境(JRE)、文档生成器等工具,用于Java程序的开发和运行。 2. JVM (Java Virtual Machine):Java虚拟机,是一种用于运行Java字节码的虚拟机,它将字节码解释成操作系统的指令,保证Java程序的跨平台特性。 3. 包 (Package):在Java中,包用于将类和接口进行分组,提供了命名空间管理,避免类名冲突。 4. 不可变类及不可变对象 (Immutable Class & Immutable Object):不可变类是指其实例一旦创建后,其状态就不能更改的类;不可变对象是指一旦创建后就不能被修改的对象。 5. UML (Unified Modeling Language):统一建模语言,是一种标准化的建模语言,用于软件工程中的对象建模和系统设计。 6. 关联 (Association):在UML中,表示两个类之间的关系,通常用线连接,表示类之间的一般关系。 7. 组合 (Composition):组合是一种强依赖的关系,表示一个类是另一个类的一部分,且它们的生命周期紧密相关。 8. 聚集 (Aggregation):聚集是表示整体与部分之间关系的一种特殊关联,部分可以在整体之外独立存在。 9. 类抽象 (Class Abstraction):抽象是指对现实世界中对象的共性进行提取,忽略细节以形成类的过程。 10. 类的合约 (Class Contract):类的合约定义了类在外部可见的行为规范,通常通过类的接口来描述。 11. 类的封装 (Encapsulation):封装是将数据和操作隐藏在类内部,通过对外提供的接口进行访问和修改,保护类的内部实现不被外部依赖破坏。 12. 可见性修饰符 (Visibility Modifiers):用于控制类、方法和变量的访问权限。主要有public, protected, default, private四种修饰符。 13. 包装类 (Wrapper Class):将基本数据类型(如int, char等)包装为对象的类,例如Integer, Character。 14. 装箱 (Boxing):将基本数据类型转换为其对应的包装类对象的过程。 15. 开箱 (Unboxing):将包装类对象转换为基本数据类型的过程。 16. 构造方法链 (Constructor Chaining):在一个类的多个构造方法之间通过调用this()或super()形成调用链。 17. 动态绑定 (Dynamic Binding):在运行时根据对象的实际类型来调用对应方法的机制,而不是在编译时决定。 18. instanceof运算符:用于测试一个对象是否是某个类的实例。 19. super关键字:用于引用父类对象,调用父类的方法或构造方法。 20. this关键字:指向当前对象的引用,通常用于区分成员变量和局部变量或调用当前类的构造方法。 21. 面向对象三大支柱:封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。 22. 重写 (Override):子类提供了父类方法的具体实现,方法签名相同,目的是替代或扩展父类的功能。 23. 重载 (Overload):同一个类中多个方法具有相同的方法名,但参数列表不同。 24. 异常 (Exception):程序运行过程中出现的错误或意外事件,异常机制用于处理这些错误。 25. 异常类的继承体系: 26. Error:严重的错误,通常不可恢复。 Exception:一般的异常,程序可以捕获并处理。 RuntimeException:运行时异常,是Exception的子类,表示在程序运行时可能出现的逻辑错误。 NullPointerException:空指针异常,表示在引用空对象时尝试调用其方法或字段。 ArrayIndexOutOfBoundsException:数组索引越界异常,表示访问数组时使用了非法索引。 运行时异常 (Runtime Exception):编译时不强制处理的异常,程序可以选择捕获或不捕获。 27. 必检异常 (Checked Exception):编译时必须处理的异常,程序员必须捕获或声明抛出。 28. 免检异常 (Unchecked Exception):同运行时异常,编译器不强制检查的异常。 29. 链式异常 (Chained Exception):允许一个异常包含另一个异常的信息,以便追踪问题的根源。 30. 标记接口 (Marker Interface):不包含任何方法,仅用于标识类具有某种属性或行为的接口,如Serializable。 31. 深复制 (Deep Copy):复制对象时,不仅复制对象本身,还复制其引用的所有对象,创建独立的对象副本。 32. 浅复制 (Shallow Copy):复制对象时,仅复制对象本身,而引用的对象仍指向原始对象。 33. 抽象类 (Abstract Class):不能被实例化的类,通常包含抽象方法,需要子类实现这些方法。 34. 接口 (Interface):定义一组方法规范,不包含实现,类可以通过实现接口来遵循这些规范。 35. 子接口 (Sub Interface):继承自另一个接口的接口,扩展了父接口的功能。
面向对象概述
面向对象三大特性
封装:
封装是面向对象编程的基本原则之一,用于隐藏对象的内部状态和实现细节,只暴露必要的接口。这样可以提高代码的安全性和可维护性。
继承:
继承是面向对象编程的一个核心特性,它允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码的重用和层次化组织。
多态:
多态是面向对象编程的一个重要特性,它允许不同的对象以相同的接口来响应相同的消息或方法调用。多态通过方法重写(override)和方法重载(overload)实现,提高了程序的灵活性和扩展性。
多态的实现
运行时多态
(动态绑定):基于对象的实际类型调用方法。在Java中,主要通过方法重写实现。编译时多态
(静态绑定):基于方法的参数列表调用方法。在Java中,主要通过方法重载实现。
2. 抽象类与接口
- 抽象类: 不能被实例化的类,它可以包含抽象方法(没有实现的方法)和具体方法(有实现的方法)。子类必须实现抽象类的抽象方法。
- 接口: 仅包含方法签名,不包含方法实现。Java的类可以实现多个接口,但只能继承一个类。
3. this和super关键字
- this: 代表当前对象的引用。可以用于区分成员变量与局部变量,或在构造方法中调用另一个构造方法。
- super: 代表父类对象的引用。可以用于访问父类的成员变量、方法以及构造方法。
class Animal { String name; Animal(String name) { this.name = name; }}class Dog extends Animal { Dog(String name) { super(name); // 调用父类的构造方法 }}
Java关键字
switch case语句
switch(status){case status_1: code_1break;case status_2: code_2break;case status_3: code_3break;default: code_4}
goto
goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。
final
[!NOTE]
用于修饰类、属性和方法;
-
被final修饰的类
不可以被继承
-
被final修饰的方法
不可以被重写
-
被final修饰的变量不可以被改变,
-
final修饰变量的引用
时,不变的是引用而引用指向的内容是可以改变的
final finally finalize区别
- final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
- finally一般作用在try-catch代码块中,在处理异常的时候,将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行。
- finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,对象是否可回收的判断。
this关键字的用法
this
是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。
this的用法在java中大体可以分为3种:
-
普通的直接引用,this相当于是指向当前对象本身。
-
形参与成员名字重名,用this来区分:
public Person(String name, int age) { this.name = name; this.age = age;}
- 引用本类的构造函数
class Person{ private String name; private int age; public Person() { } public Person(String name) { this.name = name; } public Person(String name, int age) { this(name); this.age = age; }}
super关键字的用法
super
可以理解为是指向自己超(父)类对象的一个指针
,而这个超类指的是离自己最近的一个父类。
super也有三种用法:
①. 普通的直接引用
与this类似,super相当于是指向当前对象的父类的引用,这样就可以用super.xxx来引用父类的成员。
②. 子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分
class Person{ protected String name; public Person(String name) { this.name = name; } } class Student extends Person{ private String name; public Student(String name, String name1) { super(name); this.name = name1; } public void getInfo(){ System.out.println(this.name); //Child System.out.println(super.name); //Father } } public class Test { public static void main(String[] args) { Student s1 = new Student(\"Father\",\"Child\"); s1.getInfo(); }}
③. 引用父类构造函数
super(参数)
:调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
this(参数)
:调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。
this与super的区别
- super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)
- this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
- super()和this()类似,区别是,super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
- super()和this()均需放在构造方法内第一行。
- 尽管可以用this调用一个构造器,但却不能调用两个。
- this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
- this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
- 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
static存在的主要意义
static的主要意义是在于创建独立于具体对象的域变量或者方法。以致于即使没有创建对象,也能使用属性和调用方法!
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
static的独特之处
被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享。
static应用场景
比较常见的static应用场景有:
-
修饰成员变量
-
修饰成员方法
-
静态代码块
-
修饰类【只能修饰内部类也就是静态内部类】
-
静态导包
static注意事项
静态只能访问静态。
非静态既可以访问非静态的,也可以访问静态的。静态方法不能访问实例对象
包装类相关
- 自动装箱与拆箱
装箱:将基本类型用它们对应的引用类型包装起来;
拆箱:将包装类型转换为基本数据类型;
- int 和 Integer 有什么区别
Java 是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java 为每一个基本数据类型都引入了对应的包装类型(wrapper class),int 的包装类就是 Integer,从 Java 5 开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
Java 为每个原始类型提供了
包装类型
:
原始类型
: boolean,char,byte,short,int,long,float,double
包装类型
:Boolean,Character,Byte,Short,Integer,Long,Float,Double
- Integer a= 127 与 Integer b = 127相等吗?
对于对象引用类型:==比较的是对象的内存地址。
对于基本数据类型:==比较的是值。
如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中的Integer对象,超过范围 a1==b1的结果是false
public static void main(String[] args) { Integer a = new Integer(3); Integer b = 3; // 将3自动装箱成Integer类型 int c = 3; System.out.println(a == b); // false 两个引用没有引用同一对象 System.out.println(a == c); // true a自动拆箱成int类型再和c比较 System.out.println(b == c); // trueInteger a1 = 128;Integer b1 = 128;System.out.println(a1 == b1); // false Integer a2 = 127;Integer b2 = 127;System.out.println(a2 == b2); // true}
异常处理
1. 异常的分类
- Error: 严重错误,一般不由程序处理,如OutOfMemoryError。
- Exception: 程序可以捕获并处理的错误。包括
RuntimeException
(如NullPointerException)和受检异常(如IOException)。
2. 异常处理机制(try-catch-finally)
- try: 监控代码,可能发生异常的代码。
- catch: 捕获并处理异常。
- finally: 无论是否发生异常,finally块中的代码都会被执行。
try { int result = 10 / 0;} catch (ArithmeticException e) { System.out.println(\"Cannot divide by zero\");} finally { System.out.println(\"This will always execute\");}
3. 自定义异常
class CustomException extends Exception { CustomException(String message) { super(message); }}
IO流
java 中 IO 流分类
- 按照流的流向划分: 分为
输入流
和输出流
; - 按照操作单元划分:分为
字节流
和字符流
; - 按照流的角色划分:
节点流
和处理流
;
InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
Files的常用方法
Files. exists():检测文件路径是否存在。Files. createFile():创建文件。Files. createDirectory():创建文件夹。Files. delete():删除一个文件或目录。Files. copy():复制文件。Files. move():移动文件。Files. size():查看文件个数。Files. read():读取文件。Files. write():写入文件。
Java常用类
1. 字符串操作
- String: 不可变字符串类。每次修改都会创建新的对象。
- StringBuilder: 可变字符串,适用于频繁修改字符串的情况。线程不安全。
- StringBuffer: 可变字符串,线程安全。
2. 集合框架
- List: 有序、可重复的集合,如
ArrayList
、LinkedList
。 - Set: 无序、不可重复的集合,如
HashSet
、TreeSet
。 - Map: 键值对形式的集合,如
HashMap
、TreeMap
。
3. 日期与时间
- LocalDate, LocalTime, LocalDateTime: Java 8引入的用于处理日期和时间的类,线程安全。
LocalDate date = LocalDate.now();LocalTime time = LocalTime.now();LocalDateTime dateTime = LocalDateTime.now();
多线程
Java中的多线程编程允许你同时执行多个任务。
1. 线程的创建与控制
Java提供了两种创建线程的方式:
- 继承
Thread
类: 通过继承Thread
类并重写run
方法创建一个新的线程。
class MyThread extends Thread { public void run() { System.out.println(\"Thread is running\"); }}public class Main { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); // 启动线程 }}
- 实现
Runnable
接口: 通过实现Runnable
接口,将run
方法定义在Runnable
接口的实现类中,然后将其传递给Thread
对象。
class MyRunnable implements Runnable { public void run() { System.out.println(\"Thread is running\"); }}public class Main { public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.start(); // 启动线程 }}
线程的控制:
- 启动线程: 使用
start()
方法启动线程。 - 暂停线程: 使用
sleep(long milliseconds)
方法使线程休眠指定的毫秒数。 - 等待线程结束: 使用
join()
方法让当前线程等待另一个线程结束。
class MyRunnable implements Runnable { public void run() { System.out.println(\"Thread is running\"); }}public class Main { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new MyRunnable()); thread.start(); thread.join(); // 等待线程执行完毕 System.out.println(\"Thread finished\"); }}
2. 线程的同步与通信
多线程编程中,多个线程可能会同时访问共享资源,导致数据不一致或其他问题。为了解决这些问题,可以使用同步机制来保证同一时间只有一个线程访问共享资源。
线程同步
synchronized
关键字: 用于锁住某个方法或代码块,使得同一时刻只有一个线程可以执行该方法或代码块。
class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; }}public class Main { public static void main(String[] args) { Counter counter = new Counter(); Thread t1 = new Thread(() -> { for (int i = 0; i < 1000; i++) { counter.increment(); } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 1000; i++) { counter.increment(); } }); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(\"Final count: \" + counter.getCount()); }}
Lock
接口: Java中的Lock
接口提供了比synchronized
更灵活的线程同步机制,可以显式地加锁和解锁。
import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class Counter { private int count = 0; private final Lock lock = new ReentrantLock(); public void increment() { lock.lock(); // 加锁 try { count++; } finally { lock.unlock(); // 解锁 } } public int getCount() { return count; }}
线程通信
wait()
和notify()
方法: 用于在线程之间进行通信,常用于生产者-消费者模式。wait()
会使当前线程进入等待状态,直到其他线程调用notify()
或notifyAll()
方法。
class SharedResource { private int value = 0; private boolean isProduced = false; public synchronized void produce() throws InterruptedException { while (isProduced) { wait(); } value++; System.out.println(\"Produced: \" + value); isProduced = true; notify(); } public synchronized void consume() throws InterruptedException { while (!isProduced) { wait(); } System.out.println(\"Consumed: \" + value); isProduced = false; notify(); }}public class Main { public static void main(String[] args) { SharedResource resource = new SharedResource(); Thread producer = new Thread(() -> { try { for (int i = 0; i < 5; i++) { resource.produce(); } } catch (InterruptedException e) { e.printStackTrace(); } }); Thread consumer = new Thread(() -> { try { for (int i = 0; i < 5; i++) { resource.consume(); } } catch (InterruptedException e) { e.printStackTrace(); } }); producer.start(); consumer.start(); }}
3. 并发工具类
Java并发包提供了丰富的工具类来帮助管理多线程操作。这些工具类可以帮助我们更好地控制线程池、执行并发任务以及实现复杂的同步机制。
ExecutorService
: 提供了一种更高效的方式来管理和调度线程。可以通过线程池来管理多个线程的执行,避免手动管理线程。
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Main { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(3); for (int i = 0; i < 5; i++) { executor.submit(() -> { System.out.println(Thread.currentThread().getName() + \" is working\"); }); } executor.shutdown(); // 关闭线程池 }}
Future
接口: 表示异步任务的结果。你可以使用Future
来检查任务是否完成、获取结果或取消任务。
import java.util.concurrent.*;public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executor = Executors.newSingleThreadExecutor(); Future<Integer> future = executor.submit(() -> { // 模拟耗时任务 Thread.sleep(2000); return 42; }); // 任务执行中... System.out.println(\"Task is executing...\"); // 获取任务结果 Integer result = future.get(); // 阻塞,直到结果可用 System.out.println(\"Task result: \" + result); executor.shutdown(); }}
Semaphore
: 一种计数信号量,用于限制同时访问资源的线程数量。
import java.util.concurrent.Semaphore;class Resource { private Semaphore semaphore = new Semaphore(1); public void accessResource() throws InterruptedException { semaphore.acquire(); // 获取许可 try { System.out.println(Thread.currentThread().getName() + \" is accessing resource\"); Thread.sleep(1000); // 模拟资源操作 } finally { semaphore.release(); // 释放许可 } }}public class Main { public static void main(String[] args) { Resource resource = new Resource(); for (int i = 0; i < 5; i++) { new Thread(() -> { try { resource.accessResource(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } }}
java反射机制
反射概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
静态编译和动态编译
静态编译
:在编译时确定类型,绑定对象
动态编译
:运行时确定类型,绑定对象
反射机制优缺点
优点: 运行期类型的判断,动态加载类,提高代码灵活度。
缺点: 性能瓶颈,反射相当于一系列解释操作,性能比直接的java代码要慢。
反射机制的应用场景
[!IMPORTANT]
反射是框架设计的灵魂。
举例:
①我们在使用JDBC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序;
②Spring框架也用到很多反射机制,最经典的就是xml的配置模式。Spring 通过 XML 配置模式装载 Bean 的过程:
- 将程序内所有 XML 或 Properties 配置文件加载入内存中;
- Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息;
- 使用反射机制,根据这个字符串获得某个类的Class实例;
- 动态配置实例的属性
Java获取反射的三种方法
1.通过new对象实现反射机制
2.通过路径实现反射机制
3.通过类名实现反射机制
public class Student { private int id; String name; protected boolean sex; public float score;}public class Get { //获取反射机制三种方式 public static void main(String[] args) throws ClassNotFoundException { //方式一(通过建立对象) Student stu = new Student(); Class classobj1 = stu.getClass(); System.out.println(classobj1.getName()); //方式二(所在通过路径-相对路径) Class classobj2 = Class.forName(\"fanshe.Student\"); System.out.println(classobj2.getName()); //方式三(通过类名) Class classobj3 = Student.class; System.out.println(classobj3.getName()); }
注解与元数据
1. 注解的定义与使用
- 注解可以用于标记类、方法、字段等,编译器或运行时可以根据注解进行处理。
2. 自定义注解
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface MyAnnotation { String value();}
补充:
Java数组的创建
//法一int[] arr1 = new int[]{1,2,3,4,5};//法二 声明、分配空间并赋值int[] arr2 = {1,2,3,4};//法三 声明数组时指定元素个数,然后赋值。此时所有的元素值均为0int[] arr3 = new int[4];//法四 声明数组名、开辟空间、赋值int[] arr4;arr4 = new int[]{0,1,2,3};//创建多维数组int[][] doubleArr1 = {{1,2,3},{4,5,6},{7,8,9}};int m = 3, n = 4, q = 5;int[][] doubleArr2 = new int[m][n]; //其中n可以省略int[][][] tArr = new int[m][n][q]; //其中n、q可以省略
for each遍历
int[] array =new int[]{1,2,3,4};for(int v:array){ System.out.println(v);}
public static void与public void的区别
区别:
这两句的区别就在于,能不能直接用类名访问。
obj3.getName());
}
## 注解与元数据### 1. 注解的定义与使用- 注解可以用于标记类、方法、字段等,编译器或运行时可以根据注解进行处理。### 2. 自定义注解```java@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface MyAnnotation { String value();}
补充:
Java数组的创建
//法一int[] arr1 = new int[]{1,2,3,4,5};//法二 声明、分配空间并赋值int[] arr2 = {1,2,3,4};//法三 声明数组时指定元素个数,然后赋值。此时所有的元素值均为0int[] arr3 = new int[4];//法四 声明数组名、开辟空间、赋值int[] arr4;arr4 = new int[]{0,1,2,3};//创建多维数组int[][] doubleArr1 = {{1,2,3},{4,5,6},{7,8,9}};int m = 3, n = 4, q = 5;int[][] doubleArr2 = new int[m][n]; //其中n可以省略int[][][] tArr = new int[m][n][q]; //其中n、q可以省略
for each遍历
int[] array =new int[]{1,2,3,4};for(int v:array){ System.out.println(v);}
public static void与public void的区别
区别:
这两句的区别就在于,能不能直接用类名访问。