0x01 前言 WMCTF 爆零了,没办法全是java不会啊,只能坐牢,所以想着尽快来学习java反序列化等知识,今天弹出了一个最简单的计算器,但是感觉还是很不舒服,仿佛第一天接触php一般,所以来过一下基础知识
0x02 action 基础 直接就是赛代码,除非需要一些不同的知识
HelloWorld.java
1 2 3 4 5 public class HelloWorld { public static void main (String[] args) { System.out.println("Hello World" ); } }
1 2 javac HelloWorld.java java HelloWorld
大小写敏感 :Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的。
类名 :对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
方法名 :所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
源文件名 :源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java 。(如果文件名和类名不相同则会导致编译错误)。
主方法入口 :所有的 Java 程序由 public static void main(String[] args) 方法开始执行。
Java修饰符
像其他语言一样,Java可以使用修饰符来修饰类中方法和属性。主要有两类修饰符:
访问控制修饰符 : default, public , protected, private
非访问控制修饰符 : final, abstract, static, synchronized
注释是和其他语言差不多的
对象和类
extends
表示继承,方法的话和正常的一样,更接近c的函数
1 2 3 4 5 6 7 8 9 10 11 12 package extend;public class Animal { String name; int age; public void eat () { System.out.println("The animal is eating" ); } public void sleep () { System.out.println("The animal is sleeping" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 package extend;public class Dog extends Animal { String breed; public void bark () { System.out.println("The dog is barking" ); } @Override public void eat () { System.out.println("The dog is eating" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package extend;public class Main { public static void main (String[] args) { Dog myDog = new Dog (); myDog.name = "Buddy" ; myDog.age = 3 ; myDog.eat(); myDog.sleep(); myDog.breed = "Golden Retriever" ; myDog.bark(); } }
封装就是private
或者protected
接口是完全抽象类,抽象类是一个没有确定方法的类,里面的方法基本用于重载
implements
类继承接口的关键词,接口关键词interface
变量类型也没啥
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 package Variables;public class RunoobTest { private int instanceVar; private static int staticVar; public void method (int paramVar) { int localVar = 10 ; instanceVar = localVar; staticVar = paramVar; System.out.println("成员变量: " + instanceVar); System.out.println("静态变量: " + staticVar); System.out.println("参数变量: " + paramVar); System.out.println("局部变量: " + localVar); } public static void main (String[] args) { RunoobTest v = new RunoobTest (); v.method(20 ); } }
小驼峰命名法(camelCase),即第一个单词首字母小写,后续单词首字母大写。
大驼峰命名法(PascalCase),即每个单词首字母大写。
常量全大写
方法参数用小驼峰,类用大驼峰
同时我发现个问题,文件打开多了不好关
1 2 Ctrl + Shift + F4 Ctrl + F4
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。
序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。
父类中的 final 方法可以被子类继承,但是不能被子类重写。并且final 类不能被继承,没有类能够继承 final 类的任何特性。
操作符
描述
例子
&
如果相对应位都是1,则结果为1,否则为0
(A&B),得到12,即0000 1100
|
如果相对应位都是 0,则结果为 0,否则为 1
(A | B)得到61,即 0011 1101
^
如果相对应位值相同,则结果为0,否则为1
(A ^ B)得到49,即 0011 0001
〜
按位取反运算符翻转操作数的每一位,即0变成1,1变成0。
(〜A)得到-61,即1100 0011
<<
按位左移运算符。左操作数按位左移右操作数指定的位数。
A << 2得到240,即 1111 0000
>>
按位右移运算符。左操作数按位右移右操作数指定的位数。
A >> 2得到15即 1111
>>>
按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。
A>>>2得到15即0000 1111
Math
和Number
这两个内置类其实之前肯定是接触过的所以直接给表格
1 2 3 4 5 6 7 8 9 10 11 public class Test { public static void main (String []args) { System.out.println("90 度的正弦值:" + Math.sin(Math.PI/2 )); System.out.println("0度的余弦值:" + Math.cos(0 )); System.out.println("60度的正切值:" + Math.tan(Math.PI/3 )); System.out.println("1的反正切值: " + Math.atan(1 )); System.out.println("π/2的角度值:" + Math.toDegrees(Math.PI/2 )); System.out.println(Math.PI); } }
floor\ceil\round
这三个东西报错注入的时候用到过
Character类以及方法
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 44 45 46 package Character;import java.lang.Character;public class CharacterExample { public static void main (String[] args) { char ch1 = 'A' ; char ch2 = '5' ; char ch3 = ' ' ; char ch4 = 'a' ; System.out.println("Is '" + ch1 + "' a letter? " + Character.isLetter(ch1)); System.out.println("Is '" + ch2 + "' a digit? " + Character.isDigit(ch2)); System.out.println("Is '" + ch3 + "' whitespace? " + Character.isWhitespace(ch3)); System.out.println("Is '" + ch4 + "' lowercase? " + Character.isLowerCase(ch4)); System.out.println("Is '" + ch1 + "' uppercase? " + Character.isUpperCase(ch1)); char lowerCaseChar = Character.toLowerCase(ch1); char upperCaseChar = Character.toUpperCase(ch4); char titleCaseChar = Character.toTitleCase(ch4); System.out.println("Lowercase of '" + ch1 + "' is: " + lowerCaseChar); System.out.println("Uppercase of '" + ch4 + "' is: " + upperCaseChar); System.out.println("Title case of '" + ch4 + "' is: " + titleCaseChar); int comparison = Character.compare(ch1, ch4); boolean isEqual = new Character (ch1).equals(new Character ('A' )); System.out.println("Comparison of '" + ch1 + "' and '" + ch4 + "': " + comparison); System.out.println("Are '" + ch1 + "' and 'A' equal? " + isEqual); int numericValue = Character.getNumericValue(ch2); boolean isIgnorable = Character.isIdentifierIgnorable('\u0000' ); boolean isStart = Character.isUnicodeIdentifierStart(ch1); boolean isPart = Character.isUnicodeIdentifierPart(ch2); System.out.println("Numeric value of '" + ch2 + "': " + numericValue); System.out.println("Is '\\u0000' ignorable in identifiers? " + isIgnorable); System.out.println("Is '" + ch1 + "' a valid start for a Unicode identifier? " + isStart); System.out.println("Is '" + ch2 + "' a valid part of a Unicode identifier? " + isPart); } }
String类就和python中的将字符串格式化差不多
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 public class StringExample { public static void main (String[] args) { String str1 = "Hello, World!" ; String str2 = "hello" ; int length = str1.length(); System.out.println("Length of '" + str1 + "': " + length); boolean isEqual = str1.equals("Hello, World!" ); boolean isEqualIgnoreCase = str1.equalsIgnoreCase("hello, world!" ); System.out.println("Are '" + str1 + "' and 'Hello, World!' equal? " + isEqual); System.out.println("Are '" + str1 + "' and 'hello, world!' equal ignoring case? " + isEqualIgnoreCase); int index = str1.indexOf('W' ); int lastIndex = str1.lastIndexOf('o' ); System.out.println("Index of 'W' in '" + str1 + "': " + index); System.out.println("Last index of 'o' in '" + str1 + "': " + lastIndex); char ch = str1.charAt(0 ); String subStr1 = str1.substring(7 ); String subStr2 = str1.substring(0 , 5 ); System.out.println("Char at index 0 in '" + str1 + "': " + ch); System.out.println("Substring from index 7 in '" + str1 + "': " + subStr1); System.out.println("Substring from index 0 to 5 in '" + str1 + "': " + subStr2); String concatStr = str1.concat(" Welcome!" ); String plusStr = str1 + " Welcome!" ; System.out.println("Concatenated string: " + concatStr); System.out.println("Plus concatenated string: " + plusStr); String replaceStr1 = str1.replace('o' , 'a' ); String replaceStr2 = str1.replace("World" , "Java" ); System.out.println("Replaced 'o' with 'a': " + replaceStr1); System.out.println("Replaced 'World' with 'Java': " + replaceStr2); String[] words = str1.split(", " ); for (String word : words) { System.out.println("Word: " + word); } String lowerCaseStr = str1.toLowerCase(); String upperCaseStr = str1.toUpperCase(); String trimmedStr = " Hello, World! " .trim(); System.out.println("Lowercase: " + lowerCaseStr); System.out.println("Uppercase: " + upperCaseStr); System.out.println("Trimmed: " + trimmedStr); } }
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
由于StringBuilder
更快,即使是不是线程安全的,也一般用它
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Test { public static void main (String args[]) { StringBuilder sb = new StringBuilder (10 ); sb.append("Runoob.." ); System.out.println(sb); sb.append("!" ); System.out.println(sb); sb.insert(8 , "Java" ); System.out.println(sb); sb.delete(5 ,8 ); System.out.println(sb); } }
1 2 3 4 5 6 7 8 9 public class Test { public static void main (String args[]) { StringBuffer sBuffer = new StringBuffer ("菜鸟教程官网:" ); sBuffer.append("www" ); sBuffer.append(".runoob" ); sBuffer.append(".com" ); System.out.println(sBuffer); } }
数组两种写法,一般用第一种
1 2 double [] myListdouble myList[]
For_each循环,不使用下标的情况下遍历数组
1 2 3 4 for (type element: array){ System.out.println(element); }
Array类处理数组的
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 import java.util.Arrays;public class ArraysExample { public static void main (String[] args) { int [] array = {5 , 2 , 8 , 1 , 9 }; Arrays.sort(array); System.out.println("Sorted array: " + Arrays.toString(array)); int index = Arrays.binarySearch(array, 5 ); System.out.println("Index of 5: " + index); int [] filledArray = new int [5 ]; Arrays.fill(filledArray, 5 ); System.out.println("Filled array: " + Arrays.toString(filledArray)); int [] copiedArray = Arrays.copyOf(array, 3 ); System.out.println("Copied array: " + Arrays.toString(copiedArray)); int [][] multiArray = {{1 , 2 }, {3 , 4 }}; String str = Arrays.deepToString(multiArray); System.out.println("Multi-dimensional array as string: " + str); int [] array1 = {1 , 2 , 3 }; int [] array2 = {1 , 2 , 3 }; boolean isEqual = Arrays.equals(array1, array2); System.out.println("Are arrays equal? " + isEqual); } }
regex要导包,并且是这样的
Pattern 类:
pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
Matcher 类:
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
PatternSyntaxException:
PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
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 package Regex;import java.util.regex.*;public class RegexMatches { public static void main ( String[] args ) { String line = "This order was placed for QT3000! OK?" ; String pattern = "(\\D*)(\\d+)(.*)" ; Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(line); if (m.find( )) { System.out.println("Found value: " + m.group(0 ) ); System.out.println("Found value: " + m.group(1 ) ); System.out.println("Found value: " + m.group(2 ) ); System.out.println("Found value: " + m.group(3 ) ); } else { System.out.println("NO MATCH" ); } } }
finalize()
方法定义在 Object
类中,因此所有 Java 类都可以继承并覆盖这个方法。当垃圾回收器确定没有其他引用指向某个对象时,它会在对象被回收之前调用该对象的 finalize()
方法。
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 package Finalize;public class FinalizeExample { @Override protected void finalize () throws Throwable { try { System.out.println("Finalize method called" ); } finally { super .finalize(); } } public static void main (String[] args) { FinalizeExample obj = new FinalizeExample (); obj = null ; System.gc(); try { Thread.sleep(1000 ); } catch (InterruptedException e) { e.printStackTrace(); } } }
0x03 小结 持续更新,记录现在是还没开始学Java Stream等等