赞
踩
Java和JavaScript虽然有不同的特点,但在一些概念和知识点上是相似的。本文从JavaScript开发者的角度出发,帮助你理解Java基础知识(反过来也行)。
// 解释型
console.log("Hello, World!");
// 编译型
public class HelloWorld {
// 所有的 Java 程序由 public static void main(String[] args) 方法开始执行
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
let undefinedVar; // undefined类型 let nullVar = null; // null类型 let boolVar = true; // boolean类型 let numVar = 10; // number类型 let strVar = 'Hello'; // string类型 let symVar = Symbol('foo'); // symbol类型 let objVar = {name: 'Tom'}; // object类型 let arrVar = [1, 2, 3]; // object类型中的数组 let funcVar = function() {}; // object类型中的函数 console.log(typeof undefinedVar); // 输出"undefined" console.log(typeof nullVar); // 输出"object" console.log(typeof boolVar); // 输出"boolean" console.log(typeof numVar); // 输出"number" console.log(typeof strVar); // 输出"string" console.log(typeof symVar); // 输出"symbol" console.log(typeof objVar); // 输出"object" console.log(typeof arrVar); // 输出"object" console.log(typeof funcVar); // 输出"function"
let undefinedVar: undefined = undefined; // undefined类型 let nullVar: null = null; // null类型 let boolVar: boolean = true; // boolean类型 let numVar: number = 10; // number类型 let strVar: string = 'Hello'; // string类型 let symVar: symbol = Symbol('foo'); // symbol类型 let objVar: object = {name: 'Tom'}; // object类型 let arrVar: number[] = [1, 2, 3]; // 数组类型 let funcVar: Function = function() {}; // 函数类型 console.log(typeof undefinedVar); // 输出"undefined" console.log(typeof nullVar); // 输出"object" console.log(typeof boolVar); // 输出"boolean" console.log(typeof numVar); // 输出"number" console.log(typeof strVar); // 输出"string" console.log(typeof symVar); // 输出"symbol" console.log(typeof objVar); // 输出"object" console.log(typeof arrVar); // 输出"object" console.log(typeof funcVar); // 输出"function"
// 基本数据类型 byte byteVar = 123; short shortVar = 12345; int intVar = 123456789; long longVar = 123456789012345L; float floatVar = 1.23f; double doubleVar = 1.23456789; char charVar = 'A'; boolean booleanVar = true; // 引用类型 Integer integerVar = 123; // Integer String stringVar = "Hello"; // String Boolean booleanObjVar = true; // Boolean byte[] byteArrayVar = new byte[]{1, 2, 3}; // byte[] Date dateVar = new Date(); // Date Pattern patternVar = Pattern.compile("abc"); // Pattern Function<String, Integer> functionVar = String::length; // Function Math mathVar = Math; // Math Object objectVar = new Object(); // Object System.out.println(byteVar); // 输出123 System.out.println(shortVar); // 输出12345 System.out.println(intVar); // 输出123456789 System.out.println(longVar); // 输出123456789012345 System.out.println(floatVar); // 输出1.23 System.out.println(doubleVar); // 输出1.23456789 System.out.println(charVar); // 输出A System.out.println(booleanVar); // 输出true System.out.println(integerVar.getClass().getName()); // 输出java.lang.Integer System.out.println(stringVar.getClass().getName()); // 输出java.lang.String System.out.println(booleanObjVar.getClass().getName()); // 输出java.lang.Boolean System.out.println(byteArrayVar.getClass().getName()); // 输出[B System.out.println(dateVar.getClass().getName()); // 输出java.util.Date System.out.println(patternVar.getClass().getName()); // 输出java.util.regex.Pattern System.out.println(functionVar.getClass().getName()); // 输出java.util.function.Function System.out.println(mathVar.getClass().getName()); // 输出java.lang.Math System.out.println(objectVar.getClass().getName()); // 输出java.lang.Object
注意:在Java中,数组使用大括号{}来初始化,而不是中括号[]。
// 数组
const arr = [1, 2, 3];
// Map
const map = new Map();
map.set('name', 'Tom');
map.set('age', 18);
// Set
const set = new Set();
set.add(1);
set.add(2);
// 数组 int[] arr = {1, 2, 3}; // List List<String> list = new ArrayList<>(); list.add("Tom"); list.add("Jerry"); // Map Map<String, Integer> map = new HashMap<>(); map.put("Tom", 18); map.put("Jerry", 20); // Set Set<Integer> set = new HashSet<>(); set.add(1); set.add(2); // Queue Queue<String> queue = new LinkedList<>(); queue.offer("Tom"); queue.offer("Jerry"); // Stack Stack<String> stack = new Stack<>(); stack.push("Tom"); stack.push("Jerry");
// 泛型变量T表示任意类型
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("Hello"); // output的类型为string
// 泛型变量T表示任意类型
public class Box<T> {
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
Box<Integer> box = new Box<Integer>(); // box存储的是Integer类型
box.set(10);
int num = box.get();
let num1 = "10";
let num2 = Number(num1); // 将字符串转换为数字
let str1 = 123;
let str2 = String(str1); // 将数字转换为字符串
let bool1 = 1;
let bool2 = Boolean(bool1); // 将数字转换为布尔值
int num1 = Integer.parseInt("10"); // 将字符串转换为数字
String str1 = Integer.toString(123); // 将数字转换为字符串
boolean bool1 = (1 == 1); // 将数字转换为布尔值
Java中的强制类型转换和继承相关,可以将子类类型强制转换为父类类型,这种转换是安全的,反之则是不安全的。
class Animal { public void eat() { System.out.println("Animal is eating"); } } class Dog extends Animal { public void bark() { System.out.println("Dog is barking"); } } public class Main { public static void main(String[] args) { Animal animal1 = new Animal(); Dog dog1 = new Dog(); Animal animal2 = dog1; // 子类类型强制转换为父类类型 Dog dog2 = (Dog) animal2; // 父类类型强制转换为子类类型 animal1.eat(); // 输出Animal is eating dog1.eat(); // 输出Animal is eating,子类继承了父类的方法 dog1.bark(); // 输出Dog is barking animal2.eat(); // 输出Animal is eating,子类类型被强制转换为了父类类型 dog2.eat(); // 输出Animal is eating,父类类型被强制转换为了子类类型 dog2.bark(); // 输出Dog is barking,子类类型被强制转换为了子类类型 } }
let num1 = 10;
let num2 = new Number(num1); // 显示装箱
let num3 = num2.valueOf(); // 显示拆箱
let sum = num2 + 5; // 隐式装箱和拆箱
console.log(sum); // 输出15
在Java中,基本数据类型不能直接转换为对象类型,但是Java提供了自动装箱和拆箱的功能。自动装箱是将基本数据类型自动转换为对应的包装类,自动拆箱是将包装类自动转换为对应的基本数据类型。
Integer num1 = 10; // 自动装箱
int num2 = num1; // 自动拆箱
int num3 = num1.intValue(); // 显式拆箱
int sum = num1 + 5; // 自动装箱和拆箱
System.out.println(sum); // 输出15
JavaScript 中的变量(Variable)是一种用于存储数据值的标识符,可以通过 var、let、const 关键字来声明变量。在 JavaScript 中,变量可以存储任何类型的值,可以动态改变其值的类型。例如:
var name = "Tom"; // 使用 var 声明变量
let age = 18; // 使用 let 声明变量
const PI = 3.14; // 使用 const 声明常量
name = "Jerry"; // 动态改变变量的值
TypeScript 和 Java 中的变量与 JavaScript 中的变量类似,但是在类型系统上更加严格。在 TypeScript 和 Java 中,变量可以具有明确的类型,类型一旦确定就不能再改变。
TypeScript 中的变量:使用 let 或 const 关键字来声明变量,可以使用类型注解来指定变量的类型,也可以根据上下文自动推断变量的类型。例如:
let name: string = "Tom"; // 使用类型注解指定变量类型
let age = 18; // 自动推断变量类型为 number
const PI: number = 3.14; // 使用类型注解指定常量类型
name = "Jerry"; // 动态改变变量的值
Java 中的变量:使用基本数据类型或引用数据类型来声明变量,可以使用类型标识符来指定变量的类型。例如:
String name = "Tom"; // 使用类型标识符指定变量类型
int age = 18; // 使用基本数据类型来声明变量
final double PI = 3.14; // 使用 final 关键字声明常量
name = "Jerry"; // 动态改变变量的值
const
关键字定义,一旦被定义,就不能再被重新赋值。常量的命名规则和变量相同,但通常使用全大写字母。// 定义常量PI
const PI = 3.1415926;
// 以下代码会报错:Assignment to constant variable.
PI = 3;
final
关键字定义,一旦被定义,就不能再被重新赋值。常量的命名规则和变量相同,但通常使用全大写字母。break case catch class const
continue debugger default delete do
else export extends false finally
for function if import in
instanceof new null return super
switch this throw true try
typeof var void while with
abstract continue for new switch
assert default if package synchronized
boolean do goto private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp volatile
const float native super while
不用全记住,混个眼熟,IDE会帮你记住。
如果你在犹豫这个词是不是关键字,那就不要用。
JavaScript 中的字面量(Literal)是一种表示常量值的语法形式,包括字符串字面量、数值字面量、布尔字面量、对象字面量、数组字面量等。例如:
let name = "Tom"; // 字符串字面量
let age = 18; // 数值字面量
let isMale = true; // 布尔字面量
let person = { // 对象字面量
name: "Tom",
age: 18,
isMale: true
};
let numbers = [1, 2, 3, 4, 5]; // 数组字面量
TypeScript 中的字面量包括字符串字面量、数值字面量、布尔字面量、对象字面量、数组字面量等,与 JavaScript 中的字面量相同。例如:
let name: string = "Tom"; // 字符串字面量
let age: number = 18; // 数值字面量
let isMale: boolean = true; // 布尔字面量
let person: { name: string, age: number, isMale: boolean } = { // 对象字面量
name: "Tom",
age: 18,
isMale: true
};
let numbers: number[] = [1, 2, 3, 4, 5]; // 数组字面量
Java 中也有类似的字面量表示方式,称为字面值(Literal Value),包括字符串字面值、整数字面值、浮点数字面值、布尔字面值、字符字面值、null 字面值等。例如:
String name = "Tom"; // 字符串字面值
int age = 18; // 整数字面值
double height = 1.75; // 浮点数字面值
boolean isMale = true; // 布尔字面值
char gender = 'M'; // 字符字面值
Object obj = null; // null 字面值
// 算术运算符
let a = 1, b = 2;
console.log(a + b); // 3
console.log(a - b); // -1
console.log(a * b); // 2
console.log(a / b); // 0.5
console.log(a % b); // 1
// 算术运算符
int a = 1, b = 2;
System.out.println(a + b); // 3
System.out.println(a - b); // -1
System.out.println(a * b); // 2
System.out.println(a / b); // 0
System.out.println(a % b); // 1
// 比较运算符
console.log(a === b); // false
console.log(a !== b); // true
console.log(a > b); // false
console.log(a < b); // true
console.log(a >= b); // false
console.log(a <= b); // true
// 比较运算符
System.out.println(a == b); // false
System.out.println(a != b); // true
System.out.println(a > b); // false
System.out.println(a < b); // true
System.out.println(a >= b); // false
System.out.println(a <= b); // true
// 逻辑运算符
let c = true, d = false;
console.log(c && d); // false
console.log(c || d); // true
console.log(!c); // false
// 逻辑运算符
boolean c = true, d = false;
System.out.println(c && d); // false
System.out.println(c || d); // true
System.out.println(!c); // false
// 位运算符
let e = 3, f = 5;
console.log(e & f); // 1
console.log(e | f); // 7
console.log(e ^ f); // 6
console.log(~e); // -4
console.log(f << 1); // 10
console.log(f >> 1); // 2
console.log(f >>> 1); // 2
// 位运算符
int e = 3, f = 5;
System.out.println(e & f); // 1
System.out.println(e | f); // 7
System.out.println(e ^ f); // 6
System.out.println(~e); // -4
System.out.println(f << 1); // 10
System.out.println(f >> 1); // 2
System.out.println(f >>> 1); // 2
// 条件语句
let a = 1;
if (a === 1) {
console.log("a is 1");
} else if (a === 2) {
console.log("a is 2");
} else {
console.log("a is neither 1 nor 2");
}
// 条件语句
int a = 1;
if (a == 1) {
System.out.println("a is 1");
} else if (a == 2) {
System.out.println("a is 2");
} else {
System.out.println("a is neither 1 nor 2");
}
// for循环 for (let i = 0; i < 10; i++) { console.log(i); } // while循环 let j = 0; while (j < 10) { console.log(j); j++; } // do-while循环 let k = 0; do { console.log(k); k++; } while (k < 10);
// for循环 for (int i = 0; i < 10; i++) { System.out.println(i); } // while循环 int j = 0; while (j < 10) { System.out.println(j); j++; } // do-while循环 int k = 0; do { System.out.println(k); k++; } while (k < 10); // 增强for循环 int[] arr = {1, 2, 3, 4, 5}; for (int x : arr) { System.out.println(x); }
// 跳转语句 let c = 0; while (c < 10) { if (c === 5) { break; } console.log(c); c++; } let d = 0; while (d < 10) { if (d === 5) { d++; continue; } console.log(d); d++; }
// 跳转语句 int c = 0; while (c < 10) { if (c == 5) { break; } System.out.println(c); c++; } int d = 0; while (d < 10) { if (d == 5) { d++; continue; } System.out.println(d); d++; }
try {
// 可能会抛出异常的代码
} catch (error) {
// 异常处理代码
console.log(error.message);
} finally {
// 最终执行的代码
}
try {
// 可能会抛出异常的代码
} catch (NullPointerException e) {
// 异常处理代码
System.out.println(e.getMessage());
} catch (Exception e) {
// 异常处理代码
System.out.println(e.getMessage());
} finally {
// 最终执行的代码
}
当发生NullPointerException异常时,只会执行第一个catch块中的代码,第二个catch块中的代码不会执行。如果发生其他类型的异常,第一个catch块不会执行,而是执行第二个catch块中的代码。
需要注意的是,在多个catch块中,应该按照从小到大的顺序排列异常类型,这样可以避免某个异常被多个catch块捕获导致代码逻辑混乱。
// 函数声明
function myFunction(param1, param2) {
// 函数体
return result;
}
// 函数表达式
var myFunction = function(param1, param2) {
// 函数体
return result;
};
// 箭头函数
var myFunction = (param1, param2) => {
// 函数体
return result;
};
public static ReturnType functionName(DataType param1, DataType param2) {
// 函数体
return result;
}
function sum(a, b) {
return a + b;
}
let result = sum(1, 2);
console.log(result); // 3
public class Main {
public static void main(String[] args) {
int result = sum(1, 2);
System.out.println(result); // 3
}
public static int sum(int a, int b) {
return a + b;
}
}
function myFunction(param1) { if (typeof param1 === 'string') { // 函数体1 return result1; } else if (typeof param1 === 'number') { // 函数体2 return result2; } else { // 函数体3 return result3; } } function myFunction2() { const param1 = arguments[0] if (typeof param1 === 'string') { // 函数体1 return result1; } else if (typeof param1 === 'number') { // 函数体2 return result2; } else { // 函数体3 return result3; } } function myFunction3(...args) { const param1 = args[0] if (typeof param1 === 'string') { // 函数体1 return result1; } else if (typeof param1 === 'number') { // 函数体2 return result2; } else { // 函数体3 return result3; } }
function myFunction(param1: DataType1): ReturnType1;
function myFunction(param1: DataType2, param2: DataType3): ReturnType2;
function myFunction(param1: DataType4, param2: DataType5, param3: DataType6): ReturnType3 {
// 函数体
return result;
}
public ReturnType myFunction(DataType1 param1) {
// 函数体1
return result1;
}
public ReturnType myFunction(DataType2 param1, DataType3 param2) {
// 函数体2
return result2;
}
public ReturnType myFunction(DataType4 param1, DataType5 param2, DataType6 param3) {
// 函数体3
return result3;
}
函数递归是指函数调用自身的过程,递归函数的性能较低,容易出现栈溢出等问题。
function factorial(num) {
if (num < 0) {
return -1;
} else if (num === 0 || num === 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
public int factorial(int num) {
if (num < 0) {
return -1;
} else if (num == 0 || num == 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
JavaScript 、TS、Java详细的对象和数组知识点?请各自用code方式输出,有哪些需要注意的
let person = {
name: 'John',
age: 30,
hobbies: ['reading', 'swimming'],
greet: function() {
console.log('Hello, my name is ' + this.name);
}
};
console.log(person.name); // John
console.log(person.hobbies[0]); // reading
person.greet(); // Hello, my name is John
public class Person { private String name; private int age; private ArrayList<String> hobbies; public Person(String name, int age, ArrayList<String> hobbies) { this.name = name; this.age = age; this.hobbies = hobbies; } public String getName() { return name; } public int getAge() { return age; } public ArrayList<String> getHobbies() { return hobbies; } public void greet() { System.out.println("Hello, my name is " + name); } } public class Main { public static void main(String[] args) { ArrayList<String> hobbies = new ArrayList<String>(); hobbies.add("reading"); hobbies.add("swimming"); Person person = new Person("John", 30, hobbies); System.out.println(person.getName()); // John System.out.println(person.getHobbies().get(0)); // reading person.greet(); // Hello, my name is John } }
Java中的对象是基于类的,通过实例化类来创建对象。
对象的属性需要使用private修饰符来隐藏
通过公共的getter和setter方法来访问。Java中的对象方法需要使用public修饰符来公开访问
let arr = [1, 2, 3, 'four', true];
console.log(arr[0]); // 1
console.log(arr.length); // 5
arr.push('five');
console.log(arr); // [1, 2, 3, 'four', true, 'five']
arr.pop();
console.log(arr); // [1, 2, 3, 'four', true]
public class Main {
public static void main(String[] args) {
String[] arr = {"one", "two", "three", "four"};
System.out.println(arr[0]); // one
System.out.println(arr.length); // 4
String[] newArr = Arrays.copyOf(arr, arr.length + 1);
newArr[4] = "five";
System.out.println(Arrays.toString(newArr)); // [one, two, three, four, five]
}
}
let btn = document.getElementById("myButton");
btn.addEventListener("click", function() {
alert("Button clicked!");
});
public class Main {
public static void main(String[] args) {
JButton btn = new JButton("Click me!");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked!");
}
});
}
}
// ES6 class Person { constructor(name, age) { this.name = name; this.age = age; } sayHello() { console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`); } } let person1 = new Person("John", 30); person1.sayHello(); // Hello, my name is John and I'm 30 years old. // 在ES5中,类没有类的概念,只有构造函数和原型对象的概念 function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log("Hello, my name is " + this.name + " and I'm " + this.age + " years old."); } var person1 = new Person("John", 30); person1.sayHello(); // Hello, my name is John and I'm 30 years old.
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public void sayHello() { System.out.println("Hello, my name is " + name + " and I'm " + age + " years old."); } } public class Main { public static void main(String[] args) { Person person1 = new Person("John", 30); person1.sayHello(); // Hello, my name is John and I'm 30 years old. } }
class Person { constructor(name, age) { this.name = name; this.age = age; } sayHello() { console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`); } } class Student extends Person { constructor(name, age, grade) { super(name, age); this.grade = grade; } sayHello() { console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old. My grade is ${this.grade}.`); } } let student1 = new Student("John", 15, 9); student1.sayHello(); // Hello, my name is John and I'm 15 years old. My grade is 9. /// ES5 组合继承 function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`); } function Student(name, age, grade) { Person.call(this, name, age); this.grade = grade; } Student.prototype = new Person(); // 组合继承 Student.prototype.constructor = Student; // 修改构造函数指向 let student1 = new Student("John", 15, 9); student1.sayHello(); // Hello, my name is John and I'm 15 years old.
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public void sayHello() { System.out.println("Hello, my name is " + name + " and I'm " + age + " years old."); } } public class Student extends Person { private int grade; public Student(String name, int age, int grade) { super(name, age); this.grade = grade; } public void sayHello() { System.out.println("Hello, my name is " + name + " and I'm " + age + " years old. My grade is " + grade + "."); } } public class Main { public static void main(String[] args) { Student student1 = new Student("John", 15, 9); student1.sayHello(); // Hello, my name is John and I'm 15 years old. My grade is 9. } }
class Person { constructor(name, age) { let _name = name; // 私有属性 this.age = age; // 公共属性 this.getName = function() { // 公共方法 return _name; } this.setName = function(name) { // 公共方法 _name = name; } } sayHello() { console.log(`Hello, my name is ${this.getName()} and I'm ${this.age} years old.`); } } let person1 = new Person("John", 30); console.log(person1.age); // 30 console.log(person1.getName()); // John person1.setName("Mike"); console.log(person1.getName()); // Mike person1.sayHello(); // Hello, my name is Mike and I'm 30 years old.
public class Person { private String name; // 私有属性 protected int age; // 保护属性 public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { // 公共方法 return name; } public void setName(String name) { // 公共方法 this.name = name; } public void sayHello() { // 公共方法 System.out.println("Hello, my name is " + name + " and I'm " + age + " years old."); } } public class Student extends Person { private int grade; // 私有属性 public Student(String name, int age, int grade) { super(name, age); this.grade = grade; } public void sayHello() { // 公共方法 System.out.println("Hello, my name is " + getName() + " and I'm " + age + " years old. My grade is " + grade + "."); } } public class Main { public static void main(String[] args) { Student student1 = new Student("John", 15, 9); System.out.println(student1.age); // 15 student1.setName("Mike"); System.out.println(student1.getName()); // Mike student1.sayHello(); // Hello, my name is Mike and I'm 15 years old. My grade is 9. } }
私有属性可以通过private关键字来定义。
公共属性可以通过public关键字来定义。
保护属性可以通过protected关键字来定义。
在继承中,子类可以访问父类的保护属性。
class Person { static count = 0; // 静态属性 constructor(name, age) { this.name = name; this.age = age; Person.count++; // 静态属性的使用 } sayHello() { console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`); } static getCount() { // 静态方法 console.log(`There are ${Person.count} people.`); } } let person1 = new Person("John", 30); let person2 = new Person("Mike", 25); person1.sayHello(); // Hello, my name is John and I'm 30 years old. Person.getCount(); // There are 2 people.
public class Person { private String name; private int age; private static int count = 0; // 静态属性 public Person(String name, int age) { this.name = name; this.age = age; count++; // 静态属性的使用 } 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 void sayHello() { System.out.println("Hello, my name is " + name + " and I'm " + age + " years old."); } public static void getCount() { // 静态方法 System.out.println("There are " + count + " people."); } } public class Main { public static void main(String[] args) { Person person1 = new Person("John", 30); Person person2 = new Person("Mike", 25); person1.sayHello(); // Hello, my name is John and I'm 30 years old. Person.getCount(); // There are 2 people. } }
import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface Readonly {} class Person { @Readonly String name = "John"; } public class Main { public static void main(String[] args) throws Exception { Person person = new Person(); Field field = Person.class.getDeclaredField("name"); Readonly readonly = field.getAnnotation(Readonly.class); if(readonly != null) { field.setAccessible(true); field.set(person, "Mike"); } System.out.println(person.name); // John } }
let obj = {
name: "John",
age: null
};
let name = obj && obj.name || "Default Name";
let age = obj && obj.age || 0;
console.log(name); // John
console.log(age); // 0
console.log(obj?.getSex?.()); // undefined
// 声明注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyLog { String value() default ""; } // AOP @Aspect @Component public class MyLogAspect { private static final Logger logger = LoggerFactory.getLogger(MyLogAspect.class); @Around("@annotation(myLog)") public Object logAround(ProceedingJoinPoint joinPoint, MyLog myLog) throws Throwable { String methodName = joinPoint.getSignature().getName(); String logMsg = StringUtils.isNotBlank(myLog.value()) ? myLog.value() : methodName; logger.info("开始执行方法【{}】,日志消息:{}", methodName, logMsg); Object result = joinPoint.proceed(); logger.info("方法【{}】执行完毕,返回值:{}", methodName, result); return result; } } // 使用 @MyLog("这是一个测试方法") public String testMethod(String arg1, int arg2) { // 方法体 } // 开始执行方法【testMethod】,日志消息:这是一个测试方法 // 方法【testMethod】执行完毕,返回值:xxx
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。