Java基本知识进阶
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; } - 示例效果 .

Java基本知识进阶的更多相关文章
- 谈谈Java程序员进阶的那些知识和方向
谈谈Java程序员进阶的那些知识和方向 记得前段时间看过一篇文章谈到一种程序员叫野生程序员,战斗力极强,可以搞定一切问题,但是通常看问题抓不到本质,或者说是google/baidu/stackover ...
- Java基础知识回顾之七 ----- 总结篇
前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...
- 作为一个java高级工程师的进阶之路
本文可能可能更偏向于是内心的独白篇和面试技巧总结 一.独白 之前也面试别人,现在轮到自己找工作,怎么说呢,每个面试官的看法不一样,面试的方式就不一样,比如我面试别人我喜欢问项目中他用到了那些,然后针对 ...
- Java线程知识拾遗
知识回顾 进程与线程是常常被提到的两个概念.进程拥有独立的代码段.数据空间,线程共享代码段和数据空间,但有独立的栈空间.线程是操作系统调度的最小单位,通常一个进程会包含一个或多个线程.多线程和多进程都 ...
- Java基础知识(壹)
写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...
- java基础知识小总结【转】
java基础知识小总结 在一个独立的原始程序里,只能有一个 public 类,却可以有许多 non-public 类.此外,若是在一个 Java 程序中没有一个类是 public,那么该 Java 程 ...
- Java基础知识系列——String
最近晚上没有什么事(主要是不加班有单身),就复习了一下Java的基础知识.我复习Java基础知识主要是依据Java API和The Java™ Tutorials. 今天是第一篇,复习了一下Strin ...
- 学习Spring必学的Java基础知识
[1] Java反射知识-->Spring IoC :http://www.iteye.com/topic/1123081 [2] Java动态代理-->Spring AOP :http: ...
- 学习android学习必备的java基础知识--四大内部类
学习android必备的java基础知识--四大内部类 今天学习android课程,因为我的主专业是JAVA,但是兴趣班却有这其他专业的同学,学习android 需要具备一些java的基础知识,因此就 ...
随机推荐
- 基于MVC4+EasyUI的Web开发框架形成之旅(7)--权限控制
我在上一篇随笔<基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍>中大概介绍了基于MVC的Web开发框架的权限控制总体思路.其中的权限控制就是分为“用户登录身份验证” ...
- jpa随笔
1对多的关系 //多的一方@Entity @Table(name="car_distribute") public class DistributeCar extends Cust ...
- 看图写代码---看图写代码 阅读<<Audio/Video Connectivity Solutions for Virtex-II Pro and Virtex-4 FPGAs >>
看图写代码 阅读<<Audio/Video Connectivity Solutions for Virtex-II Pro and Virtex-4 FPGAs >> 1.S ...
- Python打包文件夹的方法小结(zip,tar,tar.gz等)
本文实例讲述了Python打包文件夹的方法.分享给大家供大家参考,具体如下: 一.zip ? 1 2 3 4 5 6 7 8 9 10 11 import os, zipfile #打包目录为zip文 ...
- msp430学习笔记-msp430g2553
C语言例程:http://wenku.baidu.com/link?url=49JzNSvt3m0fRuf8SWTEM8yEw1yzqr4lBR-QbX8FddcmjTVYnDhuR97wB60HNf ...
- Hiero扩展工具包开发小结
写了两个月,Hiero扩展工具包终于完成了,包括了7个扩展内容,从Tags的扩展到TranscodeImage任务的检查再到版本的搜索,还有新Token的创建,算是对Hiero原生程序做了一个补充,提 ...
- 解决cron无法运行报错:FAILED to authorize user with PAM (Module is unknown)
查看cron运行日志 tail -f /var/log/cron 报如下错误: May 8 10:14:01 localhost crond[9399]: (root) FAILED to autho ...
- 一加3刷不了官方recoery
遇到 target reported max download size of 直接用救砖工具,恢复出厂. http://www.oneplusbbs.com/thread-2849353-1-1.h ...
- .net 4.0 程序遇到 停止工作 appcrash ,kernelbase.dll 等提示
经测试,删除*.exe.config 中 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v ...
- WPF DataGrid添加编号列
WPF DataGrid添加编号列? 第一步:<DataGridTemplateColumn Header="编号" Width="50" MinWidt ...