1.static 2.代码块 3.继承 4.抽象类 5.接口 6.多态 7.包 8.权限修饰符 9.内部类 10.字节码 11.包装类 12.装箱&拆箱 13.正则表达式 14.异常 15.反射 16.JavaBean
点击一级标题返回顶部
1.static
1.1.静态可以修饰那些?
成员变量、成员方法
1.2.静态修饰成员变量的特点?
被所有对象共享;可以使用类名调用;在创建对象之前加载到内存空间
1.3.静态的注意事项:
A.静态方法的访问范围?
可以访问静态成员变量、静态成员方法
不可以访问非静态成员变量、不可以访问非静态成员方法
B.非静态的方法可以访问哪些?
可以访问静态成员变量、静态成员方法
可以访问非静态成员变量、非静态成员方法
C.静态方法中可不可以使用this和super?
不可以
静态方法在类加载时就开始使用,这时还没有对象
1.4.静态的优缺点
记录对象共享的属性,并且单独存储。节省内存。缺点:访问局限性
2.代码块
常见的代码块:局部代码块、构造代码块、静态代码块
构造代码块的作用:提取构造方法中的共性,每次创建对象时都会执行。在构造方法执行前运行。
静态代码块的作用:初始化类、加载驱动。随着类的加载而加载。
局部代码块的作用:存在于方法中,控制变量的生命周期
3.继承
多个类,有共同的成员变量、成员方法,抽取到另外一个类中。让这多个类去继承这个类。
单一继承,一个类只可以继承一个父类;
允许多层继承,一个类可以继承一个父类,也可以作为父类被一个子类继承。
3.1.继承时的特点
子类只能获取父类的非私有成员变量;
子类中使用同名变量时,遵循就近原则。
3.1.继承时成员方法的特点
子类重写了父类方法时,调用的是自己的方法;没有重写时,直接使用父类继承而来的方法。
3.2.方法的重写
方法重写发生在子类继承父类时,两个使用相同的方法声明。重写后,子类方法覆盖父类继承来的方法。
方法重写的应用场景:
父类的方法不能满足子类的使用。使用super关键字,可以保有父类方法的功能。
方法重写的主意事项:
不能重写父类的私有方法;
修饰符权限须大于、等于父类修饰符权限。
3.3.继承时构造方法执行顺序
在有子父类继承关系的子类对象实例化时,调用子类的构造方法。如果子类调用的构造方法,第一行代码没有调用父类构造方法,则会默认调用父类的无参构造方法。
可以使用super()在子类构造中,显示调用父类构造方法。(必须出现在子类构造的第一行,否则出错)
如果在子类构造的第一行调用了子类的其他构造,那么这个构造就不去调用父类的默认构造。倘若子类中循环调用了子类的构造,则报错。
当子类构造方法 显示、隐式 调用了父类的无参构造,而父类中不存在 无参构造,则报错。(父类未定义无参构造方法)
如果子类没有调用父类的无参构造方法,就可以显示调用父类的有参构造方法。使用 super(参数列表)
不管怎么调,肯定要调用父类的构造,否则就报错。(除非,放弃继承)不仅仅是要调用父类构造,而且还要先执行父类的构造。
class F{ // public F(){ // System.out.println("f, no paras"); // } // public F(int f){ System.out.println("f, have para"); } } class Z extends F { public Z(){ // super(); //默认调用父类无参 this(3); //调用 System.out.println("z, no para"); } public Z(int z){ super(z); //调用父类有参 System.out.println("z, hava pava"); } }
实例:扩展父类功能
public class PBDemo1 extends Pdemo1{ /* * 构造方法 增加功能,实现批量执行 */ public PBDemo1(String[] sql) throws SQLException { super(sql[0]); //调用父类构造 for (int i = 1; i<sql.length; i++) { pstmt.addBatch(sql[i]); } } public PBDemo1(String[] sql, String url) throws SQLException { this(sql); //调用 setUrl(url); //调用父类方法 } }
3.4.this & super
this,当前对象的应用。super,子类对象的父类引用。(是 “父类引用”,不是 “父类对象引用”)
this,调用子类的成员变量、成员方法、构造方法(须出现在构造方法的第一行,否则报错)。
super,调用子类的父类成员变量、成员方法、构造方法(同上)。
当this调用的成员没有在子类中定义时,引用的从父类继承来的。要是不能从父类继承得到,就可能报错。
3.5.继承的优缺点
优点,提供代码的复用性,易于维护。
缺点,代码的耦合性搞了,
3.5.匿名对象
没有变量名引用的变量。
(new Student()).show();
应用场景:当方法只调用一次的时候可以使用匿名对象
3.6.final
用来修饰 类、成员方法、成员变量。final修饰后的类,不能被继承;修饰后的成员变量,不能不能修改值(可以一次性赋值,或者在构造方法中赋值);修饰的成员方法,不能被子类重写。
final修饰的成员变量,被称为“自定义常量”。
4.抽象类
4.1.什么是抽象类
使用关键字 abstract,用于修饰方法和类。修饰后的方法就是“抽象方法”,抽象方法没有方法体。修饰后的类,叫“抽象类”。
有抽象方法的类,必须是抽象类;抽象类可以不包含抽象方法。抽象类,不能实例化;使用抽象类,必须在子类中实现父类的抽象方法。
4.2.抽象类的特点
不能实例化,需要关键字 abstract 修饰,可以在抽象类中包含非抽象方法。抽象类的子类,必须实现抽象类的抽象方法,要么就必须也是抽象类。
4.3.抽象类的成员特点
可以存在成员变量,可以是常量。可以有抽象方法、非抽象方法。可以有构造函数。
注意:关键字 abstract 不能跟 final、static、private 一起出现修饰成员、类。
4.4.抽象的思想
父类不能具体某些方法内容时,使用到抽象方法;仅仅通过抽象方法来设定规则、规范。
5.接口
接口的成员特点:
- 只能有抽象方法(默认有 abstract 修饰符)
- 只能有常量
- 默认用 public abstract 修饰方法
- 默认用 public static final 修饰常量
注意:
- 接口不能创建对象(不能实例化)
- 类与接口是 实现关系。一个类实现一个接口,必须实现其所有方法。
- 接口中的抽象方法,只能用 public、abstract 修饰。
定义格式:
interface Animal { public static final int n = 15; public abstract void jump(); }
类和接口之间的关系:
- 类与类:继承关系,单一继承,多层继承
- 类与接口:实现关系,多实现
- 接口与接口:继承关系,多继承
接口的思想:
接口的优点:
- 打破继承的局限性
- 对外提供接口
- 降低了程序的耦合性
接口和抽象类的区别:
- 接口比抽象类更抽象
- 成员变量:
- 抽象类可以有成员变量,也可以有常量
- 接口只能有常量
- 成员方法:
- 抽象类可以有抽象方法,也可以有非抽象方法
- 接口只能有抽象方法(还有默认修饰符)
- 构造方法:
- 抽象类有构造方法
- 接口没有构造方法
接口和抽象类的共性:
- 不能被实例化
- 都是不断抽取共性后的一些规则
6.多态
多态的前提:
- 子父类的继承关系
- 方法的重写
- 父类引用指向子类对象
多态的成员特点:
- 成员变量 -> 编译时看的是 左边,运行时看的是 左边;成员变量没有重写这个事情;
- 成员方法 -> 编译时看的是 左边,运行时看的是 右边;
- 静态方法 -> 编译时看的是 左边,运行时看的是 左边;
多态的优点:
- 提高了代码的可扩展性
- 提高了代码的可维护性
多态的缺点:
- 无法访问子类特有成员
♣接口化程序编写。
定义接口
public abstract interface USB { public abstract void open(); public abstract void read(); public abstract void close(); }
扩展接口特性
public interface USB_IO extends USB { public abstract void write(); }
定义类实现接口
public class USB_mouse implements USB { @Override public void open() { System.out.println("鼠标加电"); } @Override public void read() { System.out.println("获取鼠标指令"); } @Override public void close() { System.out.println("鼠标断电"); } }
定义类实现接口
public class USB_Printer implements USB_IO { @Override public void open() { System.out.println("打开打印机"); } @Override public void read() { System.out.println("获取打印机当前状态"); } @Override public void write() { System.out.println("打印文件"); } @Override public void close() { System.out.println("关闭打印机"); } }
定义计算机类
public class Computer { public void useUSB(USB usb){ usb.open(); usb.read(); usb.close(); } }
public class Computer_IO extends Computer { public void useUSB(USB_IO usb){ usb.write(); super.useUSB(usb); } }
测试类
public class Test01 { public static void main(String[] args) { Computer_IO mc = new Computer_IO(); USB_mouse mouse = new USB_mouse(); USB_Printer hp = new USB_Printer(); mc.useUSB(mouse); System.out.println(); mc.useUSB(hp); } }
7.包
包的特点:
- 可以有多层
- 不同包下可以有同名文件
- 包的声明必须是文件的第一行
包之间的访问:
- 相同包
- 类之间可以直接互相访问
- 不同包
- 不能直接访问
- 需要导包,import 包名.类名;
- 使用类的全名(包名.类名)
8.权限修饰符
当前类 | 当前包 | 不同包 |
子类定义 | |
public | √ | √ | √ | √ |
protected | √ | √ | × | √ |
default | √ | √ | × | × |
private | √ | × | × | × |
- default & protected
在继承关系中,看看区别。在子类定义时看以访问到 protected (public当然也可以)。
import day04_Task02.QuanXianClass; // 导入需要继承的类 public class SonClass extends QuanXianClass { public void show(){ super.protectedShow(); protectedShow(); // 只能在子类访问该方法 } }
重写都不行,一样会报错。
@Override void defaultShow(){ // 报错 System.out.println("default"); }
9.内部类
内部类,可以理解为“类的内部类”。内部类出现在了一个类之中,在类中不同位置又有不同的叫法。内部类就像类的一个方法一样的存在,于是修饰符就跟方法一样。方法跟类比较,方法多了一个修饰符 static,那么这个内部类就比普通类也多了这么一个修饰符。这就是成员内部类的特性。而局部内部类就像一个局部变量一样存在着,更多的考虑的是有效性范围。
- 成员内部类:像是类中的一个方法一样
- 局部内部类:出现类的方法中的一个类
- 匿名内部类:没有名称的内部类,也是出现在方法中;是一个局部内部类的对象
9.1.成员内部类
定义一个成员内部类(代码中包含了内部类的调用)
public class OuterClass { public static void main(String[] args) { new OuterClass().visitInnerClass(); } public void visitInnerClass() { InnerClass ic = new InnerClass(); // 第一种方式访问内部类 ic.show(); } public class InnerClass { public void show() { System.out.println("This is outputed by inner class's method."); } } }
内部类的外部访问(算作内部类的第二种调用方式)
public class Test01 { public static void main(String[] args) { InnerClass ic = new OuterClass().new InnerClass(); } }
内部类使用外部类的成员变量(内部类的使用)
public class Task01_InnerUseVar { String name = "Outer var"; public class Inner { String name = "Inner var"; public void showName(){ String name = "Inner showName var"; System.out.println(name); System.out.println(this.name); System.out.println(Task01_InnerUseVar.this.name); } } public static void main(String[] args) { Inner ic = new Task01_InnerUseVar().new Inner(); ic.showName(); } }
内部类的静态调用
public class OutClass { public static void main(String[] args) { OutClass.InnerClass.showInnerMethod(); } public static class InnerClass{ public static void showInnerMethod(){ System.out.println("Inner method"); } } }
直接使用,如同静态方法一样
OutClass.InnerClass.showInnerMethod();
<< 内部类的外部访问(算作内部类的第二种调用方式) >>
去掉类的修饰符 static,和内部类的方法修饰符 static,后调用内部类的非静态方法
OutClass2.InnerClass oic = new OutClass2().new InnerClass(); oic.showInnerMethod();
9.2.局部内部类
定义局部内部类、调用之
class Outer { public void showOuterMethod(){ // 局部内部类,出现在成员方法中 class LocalInnerClass { public void showLocalInnerClassMethod(){ System.out.println("showLocalInnerClassMethod"); } } LocalInnerClass lic = new LocalInnerClass(); lic.showLocalInnerClassMethod(); } }
9.3.匿名内部类
- 可以看作一个没有名字的局部内部类
- 定义在方法中
- 必须在定义匿名内部类的时候,同时创建它的对象
- 创建格式:创建类,是“类名/接口名”的“子类、或者是实现类”的对象。
new 类名/接口名 (){ };
匿名内部类是局部内部类的衍化,实现接口创建对象
class Outer { void showTime() { // 使用接口实现匿名内部类的使用 new USB_i() { // 使用 接口 USB_i 创建对象 @Override public void showUSB() { // TODO Auto-generated method stub System.err.println("USB,interface implements"); } }.showUSB(); // 创建对象时,直接调用实现的接口方法 // 匿名内部类的可以赋值给一个变量 USB_i ui = new USB_i() { @Override public void showUSB() { // TODO Auto-generated method stub System.out.println("USB, interface implements as a variable."); } }; ui.showUSB(); // 使用变量调用局部内部类的方法 } } interface USB_i { public abstract void showUSB(); } abstract class USB_ac { public abstract void showUSB(); } class USB_c { public void showUSB() { System.out.println("USB, class implements"); } }
除了接口,继承类创建对象、继承抽象类实例化 创建匿名内部类
void showTime2() { // 使用接口实现匿名内部类的使用 new USB_c().showUSB(); // 创建对象时,直接调用实现的接口方法 // 匿名内部类的可以赋值给一个变量 USB_c ui = new USB_c(); ui.showUSB(); // 使用变量调用局部内部类的方法 } void showTime3() { // 使用接口实现匿名内部类的使用 new USB_ac() { // 使用 接口 USB_i 创建对象 @Override public void showUSB() { // TODO Auto-generated method stub System.err.println("USB,abstract class implements"); } }.showUSB(); // 创建对象时,直接调用实现的接口方法 // 匿名内部类的可以赋值给一个变量 USB_ac ui = new USB_ac() { @Override public void showUSB() { // TODO Auto-generated method stub System.out.println("USB, abstract class implements as a variable."); } }; ui.showUSB(); // 使用变量调用局部内部类的方法 }
- 匿名内部类的使用场景:
- 匿名类的使用,在编译后不会创建单独的 class 文件。基于这个属性,或者说在一个项目中,有一个类只使用一次,完全没有必要为其生成一个文件。
- 程序执行时,为一小段代码需要多一次文件读取,在性能角度很不值得。
10.字节码
- 字节码对象,属于整个类。包括类、以及类的对象共有。
- 获取字节码对象的方法:
- 对象,对象名.getClass()
- 类名,类名.class
- Class类的静态方法,Class.forName("类名字符串")
- 字节码对象的数据类型?Class<?>
- Class 类的实例表示正在运行的 Java应用程序中的类和接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
11.包装类
- 什么是包装类?包装了基本数据类型的类
- 意义?基本数据类型只提供了一些简单的操作和运输。包装类,提供了更多复杂的方法和一些变量。(方便使用)
- 4类8种:Byte、Short、Integer、Long、Character、Float、Double、Boolean
System.out.println(Integer.MAX_VALUE); // 20亿 十位 System.out.println(Integer.MIN_VALUE); // 表示10位 System.out.println(Integer.SIZE); // 占用32位存储空间 System.out.println(Byte.MAX_VALUE); System.out.println(Byte.MIN_VALUE); // -128 ~ 12 System.out.println(Byte.SIZE); // 占用8位存储空间 System.out.println(Short.MAX_VALUE); System.out.println(Short.MIN_VALUE); // -32768 ~ System.out.println(Short.SIZE); // 占用16位存储空间 System.out.println(Long.MAX_VALUE); // 20位 System.out.println(Long.MIN_VALUE); System.out.println(Long.SIZE); // 占用64位存储空间 System.out.println(Float.MAX_VALUE); System.out.println(Float.MIN_VALUE); // 40位 System.out.println(Float.SIZE); // 占用32位存储空间 System.out.println(Double.MAX_VALUE); System.out.println(Double.MIN_VALUE); // 300位 System.out.println(Double.SIZE); // 占用64位存储空间 System.out.println(Character.MAX_VALUE); // ??? System.out.println(Character.MIN_VALUE); System.out.println(Character.SIZE); // 占用16位存储空间
11.1.Integer
- 构造方法:没有无参构造;创建该包装类必须要有参数
构造方法 格式 |
说明 |
public Integer(int value) | 由整数构造 |
public Integer(String s) | 由整数的字符串格式构造 |
- 字段:全静态
字段 |
说明 |
public static final int MAX_VALUE | int类型表示的最小值;-231 |
public static final int MIN_VALUE | int类型表示的最大值;232 - 1 |
public static final int SIZE | 比特位数 |
public static final Class<Integer> TYPE |
System.out.println(Integer.MAX_VALUE); // 范围的最小值:2147483647 System.out.println(Integer.MIN_VALUE); // 范围的最大值:-2147483648 System.out.println(Integer.SIZE); // 占用内存的位数(bit):32 System.out.println(Integer.TYPE); // :int
常用方法 格式 |
参数 |
说明 |
|
建议 | public static Integer valudeOf(int i) | 优先使用该方法,创建实例 | |
转换 | public byte byteValue() | 以 byte 类型返回 | |
public short shortValue() | |||
public static Integer valueOf(String s) | s 可以是整数字符串、或者单个字符 | 返回 s 表示的整数 |
11.2.Boolean
- 构建 布尔 类变量
Boolean boo = Boolean.getBoolean("true");
12.装箱&拆箱
- 装箱,Jvm 把基本数据类型值转换成包装类对象
整数包装成 Integer 类型
Integer i = 10; // 把一个基本类型赋值给引用类型 // Integer i = Integer.valueOf(10);
- 拆箱,Jvm 把包装类对象转换成基本数据类型的值
int i = new Integer(10); // 也不会报错,自动拆箱 // int i = new Integer(10).intValue();
Integer i = 10; Integer j = 12; Integer sum = i + j;
13.正则表达式
- 匹配语法:
String regex = ".*e.*"; String str = "hello"; // SOP 1 Pattern p = Pattern.compile(regex); Matcher m = p.matcher(str); boolean flag = m.matches(); System.out.println(flag); // SOP 2 System.out.println(Pattern.matches(regex, str));
- 匹配规则:匹配模式表示的字符数量,须匹配到匹配对象的字符数量;一个字母 e,是匹配不到 hello 的。
- 元字符
元字符 表达式 |
说明 |
||
字符 | a | 字符 a | |
\\ | 反斜线 | ||
\r | 回车 | ||
字符类 | [abc] | a、b、c | |
[a-z] | 小写字母 | ||
预定义 | . | 任意字符 | |
\d | 数字 | ||
\D | 非数字 | ||
\s | 空白字符 | ||
\S | 非空白字符 | ||
\w | 单词字符 | 单个的 大小写字母、数字、下划线 | |
\W | 非单词字符 | ||
边界 | ^ | 行首 | |
$ | 行尾 | ||
次数 | a? | 零次或一次 | |
a* | 零次或多次 | ||
a+ | 一次或多次 | ||
a{n} | n次 | ||
a{n,} | 至少n次 | ||
a{n, m} | 至少n次、至多m次 |
14.异常
14.1.抛出异常
- 抛出“编译时异常”,创建“Exception类”对象,throw it
public static void fun(int n) throws Exception { if (n >= 4) { throw new Exception("大四异常"); } }
- 抛出“运行时异常”,创建“RuntimeException类”对象,throw it
public static void fun(String s) { if (s == null) { throw new RuntimeException("空字符串异常"); } if (s.isEmpty()) { throw new RuntimeException("字符串零长度异常"); } if (s.equals("argor")) { throw new RuntimeException("argor异常"); } }
14.2.自定义异常类
- 编译时异常,继承“Exception类”对象,重写构造方法
public class Luck98 extends Exception { public Luck98() { super(); } public Luck98(String message) { super(message); } }
- 运行时异常,继承“RuntimeException类”对象,重写构造方法
public class CongratulationsOnMakingMoney extends RuntimeException { public CongratulationsOnMakingMoney() { super(); } public CongratulationsOnMakingMoney(String message) { super(message); } }
14.3.抛出自定义异常
public static void main(String[] args) { try { fun(3); } catch (Luck98 e) { e.printStackTrace(); } } public static void fun(int n) throws Luck98{ n = 4; throw new Luck98("大四异常"); }
15.反射
反射理论:
作用:程序运行时,动态创建对象,动态调用方法,动态获取属性 反射的前题: 要有类对象(字节码对象) 获取方法:Class.forName("类名"); 反射 -> 获取构造方法 Constructor<?>[] getConstructs() 返回所有的 public 构造方法对象数组 Constructor<?> getConstruct(Class<?>... parameterTypes) 返回构造方法对象(参数是字节码对象) 不给参数时,创建一个无参构造方法对象 Constructor[] c1 = clazz.getConstructs(); Constructor c1 = clazz.getConstruct(); 给定参数时,可以获取一个指定参数列表的对象 Constructor c2 = clazz.getConstruct(String.class, int.class); Constructor[] c3 = clazz.getDeclaredConstructs(); 构造方法对象的方法: newInstance(...) 创建一个实例 c1.newInstance(); c1.newInstance("lisi", 30); 总结:字节码对象 -> 构造方法 -> 创建对象 扩展:字节码对象 -> 创建对象(只能使用无参构造) 反射 -> 获取成员变量 获取成员变量对象 Field[] fs = clazz.getFields(); public 成员变量 Field[] fs2 = clazz.getDeclaredsFields(); 所有成员变量 Field f1 = clazz.getField("age"); Field f1 = clazz.getDeclaredField("age"); 操作成员变量的值 Object objField = f1.get(obj); f1.set(obj, newValue); 反射 -> 获取私有成员变量 Class clazz = Class.forName("..."); Object obj = clazz.newInstance(); Field f = clazz.getDeclaredField("name"); f.setAccessible(true); 反射 -> 获取成员方法 Class clazz = Class.forName("..."); Object obj = clazz.newInstance(); 获取方法对象 Method[] ms = clazz.getMethods(); 获取无参无返回方法 Method m1 = clazz.getMethod("displayName"); m1.invoke(obj); 获取有参无返回方法 Method m2 = clazz.getMethod("setName", String.class); m2.invoke(obj, "huazi"); 获取无参有返回方法 Method m3 = clazz.getMethod("toString"); Object o = m3.invoke(obj);
字节码对象
Class 没有公共构造方法。Class 对象是在加载类时自动构造的。
方法格式 |
说明 |
|
字节码 | static Classe<?> forName(String name) | 获取字节码对象,字符串是一个类的全名称 |
构造方法 | Constructor<T> getConstructor(Class<?>... paraType) | |
字段 | Field getDeclareField(String name) | 获取所有声明过的字段 |
Field getField(String name) | 获取可见字段 | |
Field[] getFields() | 获取全部字段,返回一个对象数组 | |
方法 |
Method getMethod(String name, Class<?>... parameterType) | 获取可见方法 |
Method[] getMethods() | ||
Method getDeclaredMethod(String name, Class<?>... ParameterTypes ) | 参数 name 表示方法名,ParameterTypes 代表参数列表…… |
- 功能:获取构造、获取成员变量、获取成员方法
- 场景:以类为变量的应用需求(不是以对象为变量)
示例:获取构造方法
Class clazz = Class.forName("day13.Student"); // 获取字节码对象 Constructor c = clazz.getConstructor(); // 通过字节码对象获取构造方法,赋值给构造方法变量 Object obj = c.newInstance(); // 调用构造方法创建对象 System.out.println(obj); // 可以直接输出重写了 toString 方法的类对象 Constructor c2 = clazz.getConstructor(String.class, int.class); // 获取带参构造方法 Object obj2 = c2.newInstance("wangwu", 18) // 创建对象 Object obj3 = clazz.newInstance(); // 使用字节码对象的方法,也可以直接获取无参构造方法
示例:获取成员变量
Object obj = clazz.newInstance(); // 使用字节码对象创建对象 Field fs = clazz.getDeclaredField("name"); // 使用字节码对象获取字段 fs.setAccessible(true); // 设置字段可访问 fs.set(obj, "小明"); // 修改字段值
示例:获取成员字段,并直接输出字段
Class clazz = Class.forName("day13.Student"); Object obj = clazz.newInstance(); Field f1 = clazz.getDeclaredField("age"); f1.setAccessible(true); f1.set(obj, 35); System.out.println(f1.get(obj));
示例:获取成员方法
Object obj = clazz.newInstance(); // 获取对象 Method fun = clazz.getMethod("getAge"); // 无参方法 Object field1 = fun.invoke(obj); // 执行方法,获取方法的返回值 Method setName = clazz.getMethod("setName", String.class); // 有参方法的获取 setName.invoke(stu, "赵六"); // 执行方法,设定字段值
Exercise:
//反射应用模板 Class clazz = Class.forName("day13.Student"); // 获取字节码对象 // 通过字节码对象获取对象 Object obj = clazz.newInstance(); // 设置字段值 Field name = clazz.getDeclaredField("name"); name.setAccessible(true); // 私有字段 Field age = clazz.getDeclaredField("age"); age.setAccessible(true); // 私有字段 name.set(obj, "小龙"); age.set(obj, 33); System.out.println(obj); // 单独输出字段 System.out.println(age.get(obj)); // 通过字节码对象,获取方法 Method f1 = clazz.getDeclaredMethod("show"); // 调用无参 f1.setAccessible(true); // 私有方法 f1.invoke(obj); Method f2 = clazz.getDeclaredMethod("show", String.class); // 调用有参 f2.setAccessible(true); // 私有方法 f2.invoke(obj, "Times");
16.JavaBean
- 用于封装数据:
- 类使用 public 修饰
- 提供 private 修饰的成员变量
- 为成员变量提供公共 get/set 访问方法
- 提供 public 无参构造方法
- 实现序列接口(序列化,必要时须写入文件)
实例:JavaBean 实现类
import java.io.Serializable; public class Student implements Serializable { private static final long serialVersionUID = -6451757171854168084L; private String name; private int age; private int salary; public Student() { super(); } public Student(String name, int age, int salary) { super(); this.name = name; this.age = age; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", salary=" + salary + "]"; } }
- 三个常用的重要方法
方法格式 |
说明 |
static void setProperty(Object bean, String name, Object value) | 为 JavaBean 对象的成员变量 name 赋值 |
static String getProperty(Object bean, String name) | |
static void populate(Object bean, Map properties) |
示例:为 JavaBean 对象赋值
Student stu1 = new Student(); BeanUtils.setProperty(stu1, "name", "阿龙"); BeanUtils.setProperty(stu1, "age", 33); BeanUtils.setProperty(stu1, "salary", 1333);
示例: 从 JavaBean 对象获取值
String name = BeanUtils.getProperty(stu1, "name"); String age = BeanUtils.getProperty(stu1, "age"); String salary = BeanUtils.getProperty(stu1, "salary");
示例: 使用 方法 populate 为 JavaBean 赋值
Student stu1 = new Student(); Map<String, Object> map = new HashMap<String, Object>(); map.put("name", "阿龙"); map.put("age", 33); map.put("salary", 1333); BeanUtils.populate(stu1, map);
lombok
- 配置
-javaagent:lombok-1.16.18.jar -Xbootclasspath/a:lombok-1.16.18.jar
- 示例代码
package pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class Employee { private Integer id; private String lastName; private String email; private Department deptId; }
- 示例效果 .