javase基础知识笔记
1.jdk下载与环境变量配置
- 下载官网:(https://www.oracle.com/index.html)
- 配置:变量名为JAVA_HOME, 变量值为安装路径如:E:\javahome\, path值:%JAVA_HOME%bin
- win+R, 输入cmd, 回车,再输入javac -version回车查看版本,再输入 java -version 若都成功则配置安装成功。
2.基本数据类型(四型八种)
byte by = 123;//一个字节,八位
short sh = 456;//短整型,两个字节,16位
int i = 12332;//整型, 四个字节,32位
long lon = 23142342131L;//长整型,八个字节,64位
float fo = 175.9F;//单精度浮点型,四个字节,32位,
- 声明一个float类型变量,一个普通的小数默认是double类型
必须在常数的后面加上f或F
double dou = 123.87;//双精度浮点型,八个字节,64位
boolean passed = false;//boolean类型,jvm中规定,计算机底层使用int类型存储Boolean类型,所以4字节
- //字符类型变量char,可以和int整型数据类型相互转换但是不能超过最大值,\表示转义字符
`cha`r ch1 = '男';` `int a = 66;` `System.out.println("ch1对应的整型是:" + (int)ch1);//强制类型转换` System.out.println("a对应的字符型是:" + (char)a);//强制类型转换`
- /强制类型转换,从高精度向低精度转换/(需要的低数据类型)高精度数据类型例如:
float f = (float)1212.121d;
3.短路与和短路或
- boolean bool = n1 > n2 && ++n1 > n3, 如果n1>n2为flase,则后面部分则不会被执行,称为短路与。
- boolean bool2 = n1 > n2 || —n1 >n3, 如果n1>n2为真,则后面不会被执行,称为短路或。
- 按位与&和按位或|:6661. 按位与和逻辑与相似,但不会出现短路现象,按位或亦是如此。
- 按位非~类似!
4.移位运算符
左移位,表示3向左移位2位, 左移位运算<< 左移一位相当于乘2,左移两位相当于乘2的2次方。
3 <<2(3为int型)
1)把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,
2)把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,
3)在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,转换为十进制是12。
向左移动32位,结果和输入的数一样 原因:32%32==0,移动0位 如果向左移动33位,33%32==1,移动1位 结果:输入24,得到24 * 2^1 =48
右移位运算>>,右移一位相当于除2,右移n位相当于除2的n次方。无符号向右侧移动>>>,对负数有效变为正数,对整数和>>一样
5.循环
while循环:当条件为true时,可使用break;关键字跳出循环。continue;关键字表示结束本次循环,继续下一次循环。
1
2
3
4
5
6
7
8
9
10
11
12
13
14/*
* 计算出100以内所有偶数的和,偶数的和,并比较大小,输出
*/
int a = 1;
int odd_number_sum = 0;//奇数和
int even_number_sum = 0;//偶数和
while (a < 101) {
if (a % 2 == 0) {//判断为偶数
even_number_sum += a;
} else {
odd_number_sum += a;
}
a++;
}do while循环:至少执行一次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/*生成随机数,用户输入0~5的数,猜数字游戏,do while循环至少执行一次 */
Scanner scanner = new Scanner(System.in);
//生成一个随机数
Random random = new Random();//new一个生成随机数的对象
int randomNumber;
int number;
do {
System.out.println("请输入一个范围在0~5的整数:");
number = scanner.nextInt();
randomNumber = random.nextInt(5);//随机生成一个小于5的整数
if (number == randomNumber) {
System.out.println("恭喜你猜对了,随机数是" + randomNumber);
} else {
System.out.println("对不起,你猜错了,随机数是" + randomNumber);
}
} while (randomNumber != number);for循环:
1
2
3
4
5
6
7//打印九九乘法表
for (int i = 1; i <= 9; i++) {//外层循环控制换行
for (int j = 1; j <= i; j++) {//内层循环输出
System.out.print(j+ " x " + i + " = " + (i * j) + " ");
}
System.out.println();//换行
}for循环迭代:
1
2
3
4
5//for循环迭代
int[] nums = {12, 34, 567, 34, 1324, 12};//数组
for (int i : nums) {
System.out.print(i + " ");
}
6.冒泡排序
1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2、对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3、针对所有的元素重复以上的步骤,除了最后一个。
4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
1 | //冒泡排序 |
7.数组
一维数组:
String[] names = {"小米", "小明", "莱昂纳多"};
静态方式创建数组 ,数组在JVM中采用栈和堆的储存方式,通过names在栈中地址访问堆(里面为数据)int[] nums = new int[5];//指定数组长度
1
2
3
4
5
6
7
8
9
10int[] nums = {56, 28, 15, 999, 30, 65, 12, 77};
int temp;//临时变量
for (int i = 0; i < nums.length / 2; i++) {
temp = nums[i];
nums[i] = nums[nums.length - (i + 1)];
nums[nums.length - (i + 1)] = temp;
}
for (int num : nums) {
System.out.print(num + "\t");
}
二维数组
:int[][] stuScores;//声明二维数组变量
1
` stuScores = new int[3][3];//创建一个二维数组`
8.面向对象
java对象在JVM中储存:
Person person;
//声明一个自定义类型的局部变量,存储在JVM的栈中, 使用构造方法创建一个Person类型的对象;赋值给person变量, 对象存储在JVM的堆中;只有new才会在内存堆中新建一个对象person = new Person();
访问修饰符:
- public:公共的,最大访问级别。
- protected:保护的,不同包中只有子类允许访问。
- 缺省:默认的,不同包中不允许访问。
- private:私有的,只允许在本类中访问。
构造方法:
方法名称和类名完全相同,没有任何返回类型,这样的方法是构造方法(构造器)
构造方法是用来创建对象使用的,使用new 运算符调用并创建一个对象
带参数的构造器目的就是为对象进行成员属性初始化
1
2
3
4
5
6/*局部变量和成员实例属性重合时可以使用this关键字指向成员变量*/
public Employee(String name, int workAge) {
this.name = name;
this.workAge = workAge;
System.out.println(name + " " + workAge);
}如果构造器被定义多个称为构造方法重载或构造器重载,自定义有参构造器将会覆盖系统默认提供的无参构造器,如果需要使用则必须重新显示定义。
9.继承,多态,接口
- 继承:继承是类与类之间的关系,非对象与对象之间的关系,使用关键字extend, 创建子类对象时总是要先创建一个父类对象,默认子类的构造方法总是自动调用父类的无参构造方法 .
- java的三大特性:封装、继承、多态(方法重载、方法重写)。
- final关键字修饰的类不能被继承,构造方法不能被继承,final修饰的类不能被继承,不能被重写。
- 方法重载是在同一个类中,方法重写出现在子类当中
- super关键字,不能出现在静态方法中,super关键字在子类的构造方法中代表父类的构造器。
- 抽象类:
- Java核心编程思想是面向对象,面向对象核心编程思想是面向抽象。
- 不能使用final关键字修饰。
- 自身不能够实例化。
- 用来被继承。
- 适配器: 适配器(Adaptor)创建一个普通类作为适配器类,继承抽象类,实现所有抽象类方法,在用非抽象子类继承适配器,选择性重写抽象方法。
- 接口:接口中属性定义必须是公共的,静态的常量;接口中只允许定义公共的抽象的实例方法。接口中所有对象都是上转型对象。
10.静态代码块
允许访问静态属性,调用静态方法,定义局部变量及常量,定义局部类。
不允许访问实例属性和方法以及定义方法。
静态代码块属于类,和对象无关,随类的加载而加载。
1 | /*定义静态的常量*/ |
11.常用库介绍
Object类:
- 是所有类的超级父类,java任何引用类型对象都可以赋值给Object类型变量。
- Object类提供的常用方法:toString()方法;equals方法用来判定给定对象是否与当前对象相等;getClass方法返回当前对象的运行时类(Class)对象,此方法不允许子类进行重写:public final Class getClass();
Character包装类:
Character.isDigit(chars[i])
判断是否为数字Character.isLetter(chars[i])
判断是否为字母Character.isLowerCase(chars[i])
判断是否为小写字母Character.isUpperCase(chars[i])
判断是否为大写字母Character.toUpperCase(chars[i]);
字母转换为大写字母Character.toLowerCase(chars[i]);
字母转换为小写字母
Integer:
1
String strNumber = Integer.toString(number);//将整型转换为字符串
1
Integer.parseInt(String.valueOf(chars[i]));//将字符转换为字符串再转换整型
12.String字符串以及常用方法
- String str=”IU”;字符串常量不可以被更改只能被覆盖;存储在jvm堆中的静态常量区.
toCharArray();
此方法返回char型数组.contains(" ")
判断是否包含空格length();
返回字符串长度String str3 = new String(chars, 3, 8);//aChinese,3:表示索引,8:索引开始取几个
- 比较两个字符串是否相等,equals比较的是字符串的序列化值是否相等,==比较值和是否是同一个对象
- 通过索引查找字符:
charAt(index);
- 判断结尾和开始:
startsWith("我爱中国")
,endsWith("qq.com");
- 去掉字符串前后的空格:
str.trim();
- 查找字符串中指定字符索引:
email.indexOf('@')
返回字符索引值email.indexOf(".com")
返回字符串索引email.indexOf('9',0)
从指定索引查找
str.split(tag);//返回一个字符串数组
- 提取字串:
substring(3);
从索引位置开始提取substring(3, 12);//3:开索引始,12:索引结束(最后不取该值)
toLowerCase();
转换为小写toUpperCase();
转换为大写replace("小", "大");//将小替换为大
StringBuffer:
StringBuffer buffer = new StringBuffer("^_^ ")
- StringBuffer是线上安全,线程同步的
buffer.append("qwq")
连接字符串
StringBuilder:
StringBuilder stringBuilder = new StringBuilder(base);//构建可变字符串
stringBuilder.toString();//返回连接的字符串
- 非线程同步,不涉及多线程使用比StringBuffer效率更高
13.日期和时间类
- SimpleDateFormat实现对Date的字符串格式化,是DateFormat的子类
1 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
Calendar对象的创建和使用(抽象类,不能实例化对象)日历
Calendar cal = Calendar.getInstance();//使用默认时区并指向当前系统时间创建一个日历实例
1 | /*获取年月日*/ |
Date currentDate = cal.getTime();
获取当前日历对象所对应的date对象
1 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
set(int year,int month, int date);
设置日历的年份,月份,日期值
14.Math类
- 所有属性和方法都为static的,不需要创建实例,final修饰的终极类不能被继承
Math.abs(-12)
计算绝对值Math.cbrt(27.0)
计算立方根Math.max(a,b),Math.min(a,b)
比较大小Math.pow(x,y)
计算x的y次方Math.random()
返回0.0到1.0的随机数
15.集合
Map接口(HashMap不是现程安全的。HashTable是线程同步的)
1
2
3Map<String, Object> carMap = new HashMap<>(); /*存储键值对在哈希表*/ carMap.put("key0", car0);
carMap.put("key2", car2);
carMap.put("key3", car3);carMap.get("key0")
通过键取值/*获取所有键的集合*/ Set keySet = carMap.keySet();
不重复/*取出哈希表中所有的值的集合*/ Collection coll = carMap.values();
carMap.containsKey("key0")
判断是否包含给定键List集合
List<User> userList = new ArrayList<>();//创建List集合对象
userList.contains(new User())//判断集合中是否包含给定对象
userList.clear();
清空集合元素- :list中根据索引将元素数值改变(替换)注意 .set(index, element); 和 .add(index, element)
Vector集合实现类:向量集合,适用场景在处理多线程应用中
Vector<User> vector = new Vector<>();//创建集合向量
"当前集合是否为空:" + vector.isEmpty()
当前集合元素个数:" + vector.size())
vector.remove(user3);//删除元素
1
2
3
4
5/*获取Vector独有的新方法提供元素枚举迭代器*/
Enumeration enu = vector.elements();
while (enu.hasMoreElements()) {
User user = (User) enu.nextElement();//将Object类型强制转换 System.out.println(user);
}Set接口:没有索引,不能存储重复数据,会覆盖。(对象不能一样)
Set<Product> set = new HashSet<Product>(16);//指定初始容量,默认是16,会自动扩容
TreeSet类接口,排序,效率比HashSet要低
TreeSet类接口,排序
16.异常
- Throwable是所有异常的父类,Error错误重启java虚拟机才行,Exception异常修改代码可解决。
- 使用throws关键字声明异常,多个异常逗号隔开;使用throw关键字满足条件时抛出异常
1 | try {//捕获异常 |
17.File
常用构造方法:
- File(File dir,String child)
- File(String pathName)
- File(String parent,String child)
1 | File resFile = new File("f:\\file\\java.data") |
18.输入流(InputStream对目标文件进行读取操作)
读取二进制文件,字节输入流:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30/*建立目标要读取的文件对象*/
File file = new File(filePath);
/*基于目标文件建立输入流*/
InputStream in = null;
if (file.exists()) {//如果文件存在,创建文件输入流
try {
in = new FileInputStream(file);//使用子类FileInputStream创建二进制输入流
int count = 0;//读取到的字节数
byte[] bytes = new byte[124];//临时存储读取到的二进制文件
/*将读取到的字节数存储到bytes字节中,每次从索引开始存储,存储的长度是
bytes.length,覆盖*/
while ((count = in.read(bytes, 0, bytes.length)) != -1) {//循环处理读取,读到文件末尾count为-1
String s = new String(bytes, 0, count);//索引0开始,读取长度count
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();//关闭流,释放资源
System.out.println("关闭成功");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符输入流:读取文本文件不会出现乱码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23FileReader fileReader = null;
if (file.exists()) {
try {
fileReader = new FileReader(file);
int count = 0;
char[] chars = new char[30];
while ((count = fileReader.read(chars, 0, chars.length)) != -1) {
String s = new String(chars, 0, count);
System.out.print(s);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (fileReader != null) {
fileReader.close();//关闭流,释放资源
System.out.println("关闭成功");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用BufferedReader缓冲流:提高效率(字符输入流)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24FileReader fileReader = null;//基于文件的普通输入流
BufferedReader br = null;//基于某个Reader建立的字符缓冲流(处理流)
if (file.exists()) {
try {
fileReader = new FileReader(file);//基于文件建立普通文本输入流
br = new BufferedReader(fileReader);//基于某个Reader建立文本缓冲流
int count = 0;
char[] chars = new char[25];
while ((count = br.read(chars, 0, chars.length)) != -1) {
String s = new String(chars, 0, count);
System.out.print(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
19.输出流(OutputStream对目标文件进行写入操作)
二进制输出流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public static void binaryOutputStream(File file) {
String str = "start=D:\\java课程\\第十九天\\unit12 二级制输出流一(153).mp4";
byte[] bytes = str.getBytes();//将字符串转换为字节数组
OutputStream out = null;
try {
out = new FileOutputStream(file);
out.write(bytes);//调用write方法将字节数组的数据写入目标文件file
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}数据比较大时使用缓冲流:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24public static void useBufferedOutputStream(File file) {
OutputStream os = null;
BufferedOutputStream bs = null;
String str = "君不见高堂明镜悲白发,朝如青丝暮成雪。";
byte[] bys = str.getBytes();
if (file.exists()) {
try {
System.out.println(file.getAbsolutePath());
os = new FileOutputStream(file.getAbsolutePath() + "/诗词.doc");
bs = new BufferedOutputStream(os);//基于某个OutputStream建立缓冲输出流
bs.write(bys, 0, bys.length);//写入目标文件
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bs.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
20.文件的复制(流的对接)
1 | public static void copeFile(File target, File dir) { |
21.序列化读写
序列化流,将一个java对象保存到目标文件(ObjectOutputStream)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public static void javaSerializableAction(Employee emp, File file) {
OutputStream os = null;
ObjectOutputStream oos = null;//序列化流
if (emp != null) {
try {
os = new FileOutputStream(file);
oos = new ObjectOutputStream(os);
oos.writeObject(emp);//将序列化文件保存到目标文件
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
oos.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}反序列化流,从目标文件读取序列化java对象到内存(ObjectInputStream)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public static Employee deserializableJavaObject(File file) {
InputStream in = null;//创建输入流
ObjectInputStream ois = null;
Employee emp = null;
if (file.exists()) {//如果文件存在
try {
in = new FileInputStream(file);
ois = new ObjectInputStream(in);
//进行反序列化(串行化)
Object object = ois.readObject();
emp = object != null ? (Employee) object : null;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
return emp;
}
22.多线程
Thread线程类
- 任何一个Thread实例调用start方法将启动运行一个线程
- Thread的run方法是线程启动后自动执行的业务方法
线程的生命周期
- 第一阶段:新建状态(此时线程还没有运行)
- 第二阶段:运行状态(线程开始运行并自动执行run方法)
- 第三阶段:中断状态(多种原因使线程处于终止)
- 第四阶段:死亡状态(释放线程对象,不在回复运行)
Runnable线程接口:有利于实现多个线程之间的数据共享,多个Thread实例共享此接口的run方法
interrupt()方法:中断某个线程的状态
线程之间的通信
同步代码块:被同步的代码块在一个线程对象进行访问时,其他线程是没有访问权限的,只有这个当前线程对象完全执行完了这个代码块,释放了同步锁,其它线程才可以访问这个代码块。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class Syncode implements Runnable {
public void run() {
synchronized (this) {//那个类调用就是那个对象,com.znzz.multiThread.SynCode@8e6ae55
Thread current = Thread.currentThread();//获取当前线程
for (int i = 0; i < 5; i++) {
System.out.println("当前执行同步代码块的线程名称是:" + current.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}对象同步锁:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26public class SynObject implements Runnable {
private Dog dog;
public SynObject() {
if (dog == null) {
dog = new Dog();
}
}
public void run() {
synchronized (dog) {//对象同步锁
Thread current = Thread.currentThread();//获取当前线程
for (int i = 0; i < 5; i++) {
System.out.println(current.getName() + "正在修改dog名字:");
dog.setName("米卡" + i);
System.out.println("名字被修改为" + dog.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}方法同步锁:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30public class SynMethod implements Runnable {
private double money = 100000;
public void run() {
doMoney();
}
private synchronized void doMoney() {
Thread current = Thread.currentThread();
for (int i = 1; i <= 5; i++) {
if (current.getName().equals("会计")) {
System.out.println(current.getName() + " 正在入账......");
money *= i;
System.out.println("账户:" + money);
}
if (current.getName().equals("出纳")) {
System.out.println(current.getName() + " 正在分账......");
money = money * i - 0.2 * money;
System.out.println("账户:" + money);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("总帐:" + money);
}
}
23.网络编程
- IP地址:IP 地址(Internet Protocol Address)是互联网协议特有的一种地址,它是 IP 协议提供的一种统一的地址格式。IP 地址为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。与域名绑定。
- 端口号:ip地址是用来标志服务器的。但是一个服务器上会有很多个程序同时使用网络,那怎么保证他们的网络包不串线?好了,端口号就入场了,它是0-65535之间的一个数字。服务端是监听一个固定的端口,比如80,这样客户端在连接的时候都知道该连哪个应用。客户端是从未占用的里面随机挑选一个就可以(但一般不会选1024以下)。
24.枚举数据类型
- 枚举类用关键字enum修饰,用来定义不变的值,类似于final修饰的 常量;
- 枚举类中还可以定义方法,内部类,变量等,但都必须定义在枚举数据之后。
1 | /* |
25.反射编程
Java中的反射编程是通过JVM运行时获取某个类型的字节码(Class)对象,从而利用其反向获取此类型定义的内部信息实现编程的一种机制。
Class类:Class类的实例表示正在运行的Java应用程序中的类和接口,是字节码实例。
eg.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36public static void main(String[] args) {
try {
Class<?> stuClass = Class.forName("com.znzz.practice.Student");
/*使用字节码对象获取关于这个类的对象实例*/
Student student = (Student) stuClass.newInstance();//默认调用此类的无参构造实例化对象,返回对象是Object类型
System.out.println(stuClass.getName());//com.znzz.practice.Student
/*获取类的访问级别*/
System.out.println(stuClass.getModifiers() == Modifier.PUBLIC);//true
/*获取所有公共级别的字段*/
Field[] fields = stuClass.getFields();
for (Field f : fields) {
System.out.println(f);//public java.lang.String com.znzz.practice.Student.name
}
System.out.println("所有访问级别的字段数组长度:" + stuClass.getDeclaredFields().length);//3
/*获取类中定义的构造器*/
Constructor con0 = stuClass.getConstructor(String.class, Integer.class);
System.out.println(con0 != null);//true
/*获取所有构造器*/
Constructor[] constructors = stuClass.getConstructors();
System.out.println(constructors.length);//3个构造器
/*获取类中定义的方法*/
Method[] methods = stuClass.getMethods();//获取所有公共访问级别的方法,获取所有方法用stuClass.getDeclaredMethods()
System.out.println(methods.length);//11包括父类中的方法
for (Method m : methods) {
System.out.println(m.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}Constructor类:表示某个类的构造方法实例类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public static void main(String[] args) {
try {
Class<?> stuClass = Class.forName("com.znzz.practice.Student");//获取字节码对象
/*获取构造器*/
Constructor cons = stuClass.getConstructor(String.class, Integer.class);//如果无参数就是无参构造器
/*使用构造器反射方法实现对象的创建*/
Student student = (Student) cons.newInstance("李知恩", 26);//返回Object类型,强制类型转换
System.out.println(student.getName() + " " + student.getAge());
System.out.println("构造器的参数个数是:" + cons.getParameterCount());//2
System.out.println(cons.getModifiers() == Modifier.PUBLIC);//构造器的访问级别 true
System.out.println(cons.getName());//com.znzz.practice.Student
} catch (Exception e) {
e.printStackTrace();
}
}Filed和Method类反射编程:Field提供有关类或接口的单个字段信息,以及对它的动态访问权限。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44public class TestFieldAndMethod {
public static void main(String[] args) {
try {
Class<?> stuClass = Class.forName("com.znzz.practice.Student");//加载类
Student student = (Student) stuClass.newInstance();//通过反射获取一个实例对象
/*获取某个成员字段*/
Field nameField = stuClass.getField("name");//获取公共级别的属性字段
nameField.set(student, "lisa");//为公共字段赋值
/*使用反射获取某个对象字段的属性值*/
System.out.println(nameField.get(student));//lisa
/*获取不可见的字段属性private*/
Field ageField = stuClass.getDeclaredField("age");
if (ageField.getModifiers() == Modifier.PRIVATE) {
/*运行时动态改变私有字段的访问级别*/
ageField.setAccessible(true);//访问级别设置为public
ageField.set(student, 28);
System.out.println(ageField.get(student));//28
}
Field sexField = stuClass.getDeclaredField("sex");
if (!sexField.isAccessible()) {
sexField.setAccessible(true);
sexField.set(student, "女");
System.out.println(sexField.get(student));
}
/*Method反射编程*/
Book book = new Book();
book.setName("《红楼梦》");
Method method = stuClass.getMethod("learn", Book.class);//方法名,参数类型
method.invoke(student, book);//执行方法
/*获取非公共可见级别的方法*/
Method method2 = stuClass.getDeclaredMethod("run");
if (!method2.isAccessible()) {//如果访问级别不是公共可见的
method2.setAccessible(true);//运行时更改此方法的访问级别
method2.invoke(student);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}