Java 언어에서는 바이트 코드 기능을 사용할 수 없습니다.
현재 (Java 6) 자바 바이트코드로 할 수 있는 것 중 자바 언어에서는 할 수 없는 것이 있습니까?
저는 둘 다 튜링의 완전성을 알고 있기 때문에 "can do"를 "훨씬 더 빠르게/더 좋게, 또는 단지 다른 방법으로"로 읽으세요.
다른 바이트 코드도 생각해보고 있는데invokedynamic
특정 버전이 미래 버전이라는 점을 제외하고 Java를 사용하여 생성할 수 없습니다.
Java 바이트 코드로 오랜 시간 작업한 후 이 문제에 대해 몇 가지 추가 조사를 수행한 후, 다음과 같이 저의 결과를 요약합니다.
슈퍼 컨스트럭터 또는 보조 컨스트럭터를 호출하기 전에 컨스트럭터에서 코드를 실행합니다.
Java 프로그래밍 언어(JPL)에서 생성자의 첫 번째 문은 슈퍼 생성자 또는 같은 클래스의 다른 생성자를 호출하는 것이어야 합니다.이것은 Java 바이트 코드(JBC)에 대해서는 해당되지 않습니다.바이트 코드 내에서는 다음과 같은 경우 컨스트럭터 전에 어떤 코드도 실행하는 것이 절대적으로 합법적입니다.
- 이 코드 블록 뒤에 호환되는 다른 생성자가 호출됩니다.
- 이 콜은 조건부 스테이트먼트에 포함되지 않습니다.
- 이 컨스트럭터를 호출하기 전에 생성된 인스턴스의 필드는 읽히지 않으며 해당 메서드는 호출되지 않습니다.이것은 다음 항목을 암시합니다.
슈퍼 컨스트럭터 또는 보조 컨스트럭터를 호출하기 전에 인스턴스 필드 설정
앞에서 설명한 바와 같이 다른 컨스트럭터를 호출하기 전에 인스턴스의 필드 값을 설정하는 것은 완전히 합법적입니다.이 "기능"을 6 이전 버전의 Java에서 이용할 수 있는 레거시 해킹도 있습니다.
class Foo {
public String s;
public Foo() {
System.out.println(s);
}
}
class Bar extends Foo {
public Bar() {
this(s = "Hello World!");
}
private Bar(String helper) {
super();
}
}
이렇게 하면 슈퍼 컨스트럭터를 호출하기 전에 필드를 설정할 수 있지만 더 이상 실행할 수 없습니다.JBC 에서는, 이 동작을 실장할 수 있습니다.
슈퍼 컨스트럭터 호출 분기
자바에서는 컨스트럭터 호출을 다음과 같이 정의할 수 없습니다.
class Foo {
Foo() { }
Foo(Void v) { }
}
class Bar() {
if(System.currentTimeMillis() % 2 == 0) {
super();
} else {
super(null);
}
}
Java 7u23까지는 HotSpot VM의 검증자가 이 체크를 놓쳤기 때문에 가능했습니다.이것은 여러 코드 생성 툴에 의해 일종의 해킹으로 사용되었지만, 이러한 클래스를 구현하는 것은 더 이상 합법적이지 않습니다.
후자는 이 컴파일러 버전의 버그에 불과합니다.새로운 컴파일러 버전에서도 이 기능은 사용할 수 있습니다.
생성자가 없는 클래스 정의
Java 컴파일러는 항상 모든 클래스에 대해 적어도 하나의 컨스트럭터를 구현합니다.Java java java java java java java java java java java java java java java java java.이를 통해 리플렉션 사용 시에도 구성할 수 없는 클래스를 만들 수 있습니다. ,를 sun.misc.Unsafe
에서는 이러한 인스턴스를 생성할 수 있습니다.
서명은 같지만 반환 유형이 다른 메서드를 정의합니다.
JPL에서는 메서드는 이름 및 원시 파라미터 유형에 따라 고유한 것으로 식별됩니다.JBC에서는 raw 리턴 타입이 추가로 고려됩니다.
이름별로 다르지 않고 유형별로만 다른 필드 정의
클래스 파일에는 다른 필드 유형을 선언하는 한 동일한 이름의 여러 필드를 포함할 수 있습니다.JVM은 항상 필드를 이름과 유형의 튜플이라고 합니다.
선언되지 않은 선택된 예외를 탐지하지 않고 던집니다.
Java 런타임 및 Java 바이트 코드는 선택된 예외의 개념을 인식하지 않습니다.Java 컴파일러만이 체크된 예외가 항상 검출되거나 느려질 경우 선언되는지 확인합니다.
람다 식 외부에서 동적 메서드 호출 사용
이른바 동적 메서드 호출은 Java의 람다 식뿐만 아니라 모든 것에 사용할 수 있습니다.이 기능을 사용하면 예를 들어 실행 시 실행 로직을 전환할 수 있습니다.JBC로 요약되는 많은 동적 프로그래밍 언어는 이 명령을 사용하여 성능을 향상시켰습니다.Java 바이트 코드에서는 Java 7에서 람다 식을 에뮬레이트할 수도 있습니다.이 경우 컴파일러는 아직 동적 메서드 호출 사용을 허용하지 않았지만 JVM은 이미 명령을 이해하고 있습니다.
일반적으로 합법적이라고 간주되지 않는 식별자 사용
메서드 이름에 공백과 줄 바꿈을 사용하는 것을 생각해 본 적이 있습니까?JBC 방송입니다.식별자에 대한 유일한 잘못된 문자는 다음과 같습니다..
,;
,[
★★★★★★★★★★★★★★★★★」/
이름이 되지 않은 도 있습니다<init>
★★★★★★★★★★★★★★★★★」<clinit>
할 수 <
★★★★★★★★★★★★★★★★★」>
.
" " "final
「」의 어느쪽인가.this
final
파라미터는 JBC에 존재하지 않기 때문에 재할당할 수 있습니다.의 파라미터를 한다).this
.JVM을 할 수 .this
0
단일 메서드 프레임 내에서.
" " "final
표시
컨스트럭터 내에서 최종 필드가 할당되어 있는 한 이 값을 재할당하거나 값을 전혀 할당하지 않아도 됩니다.따라서 다음 두 개의 컨스트럭터가 합법적입니다.
class Foo {
final int bar;
Foo() { } // bar == 0
Foo(Void v) { // bar == 2
bar = 1;
bar = 2;
}
}
★★★의 static final
필드에서는 클래스 이니셜라이저 외부에 필드를 재할당할 수도 있습니다.
생성자와 클래스 이니셜라이저를 메서드인 것처럼 취급합니다.
이는 개념적인 기능에 가깝지만 컨스트럭터는 JBC 내에서 일반 메서드와 다르게 취급되지 않습니다.JVM의 검증자만이 컨스트럭터가 다른 법적 컨스트럭터를 호출할 수 있도록 합니다.그 외에는 생성자를 호출해야 하는 자바 명명 규칙일 뿐입니다.<init>
가 '클래스 이니셜라이저'라고 .<clinit>
이 차이점 외에 방법 및 생성자의 표현은 동일합니다.한 것처럼 Holger 이외의 컨스트럭터를 .void
또는 인수가 있는 클래스 이니셜라이저(이러한 메서드를 호출할 수 없음)를 지정합니다.
비대칭 레코드 작성*
레코드를 작성할 때
record Foo(Object bar) { }
은 javac이라는 이름의 단일 합니다.bar
「」라고 하는 이름의 액세스 .bar()
(컨스트럭터)를 하고 있습니다.Object
, 의 bar
을 사용하다레코드를 수동으로 생성함으로써 다른 컨스트럭터 모양을 생성하여 필드를 건너뛰고 접근자를 다르게 구현할 수 있습니다.동시에, 반사 API가 클래스가 실제 레코드를 나타낸다고 믿게 할 수도 있습니다.
임의의 슈퍼 메서드를 호출합니다(Java 1.1까지).
단, 이는 Java 버전1 및 1.1에서만 가능합니다.JBC에서는 메서드는 항상 명시적인 타깃타입으로 디스패치 됩니다.즉,
class Foo {
void baz() { System.out.println("Foo"); }
}
class Bar extends Foo {
@Override
void baz() { System.out.println("Bar"); }
}
class Qux extends Bar {
@Override
void baz() { System.out.println("Qux"); }
}
했습니다.Qux#baz
Foo#baz
Bar#baz
다이렉트 슈퍼 클래스 이외의 다른 슈퍼 메서드 구현을 호출하는 명시적 호출을 정의할 수 있지만, 이는 1.1 이후 Java 버전에서는 더 이상 효과가 없습니다.1.이 동작이 1.을 되었습니다.ACC_SUPER
이 플래그는 직접 슈퍼 클래스의 구현만 호출하는 동일한 동작을 활성화합니다.
같은 클래스에서 선언된 메서드의 비가상 콜을 정의합니다.
Java에서는 클래스를 정의할 수 없습니다.
class Foo {
void foo() {
bar();
}
void bar() { }
}
class Bar extends Foo {
@Override void bar() {
throw new RuntimeException();
}
}
""가 .RuntimeException
때foo
는 의 인스턴스에서 호출됩니다.Bar
는할 수 .Foo::foo
독자적인 호출 방법 bar
되어 있는 Foo
~ . 。bar
는 비프라이빗 인스턴스 방식이며 콜은 항상 가상입니다., 하여 ""를 할 수 .INVOKESPECIAL
링크하는 .bar
in 「 」Foo::foo
로로 합니다.Foo
의 버전입니다.이 opcode는 보통 슈퍼 메서드 호출 구현에 사용되지만 opcode를 재사용하여 설명한 동작을 구현할 수 있습니다.
세분화된 유형의 주석
은 주석에 됩니다.@Target
이치노바이트 코드 조작을 사용하면 이 컨트롤과 독립적으로 주석을 정의할 수 있습니다. 예를 , 을 달지 , 파라메타에 달 수 있다.@Target
을 사용법
유형 또는 구성원에 대한 속성 정의
Java 언어 내에서 필드, 메서드 또는 클래스에 대한 주석만 정의할 수 있습니다.JBC에서는 기본적으로 Java 클래스에 모든 정보를 포함할 수 있습니다.그러나 이 정보를 이용하려면 Java 클래스 로딩 메커니즘에 의존할 수 없지만 메타 정보를 직접 추출해야 합니다.
및 인 할당byte
,short
,char
★★★★★★★★★★★★★★★★★」boolean
(values
후자의 원시 유형은 일반적으로 JBC에서는 알려져 있지 않지만 배열 유형 또는 필드 및 메서드 기술자에 대해서만 정의됩니다. 코드 32비트를 32비트는 이를 코드 명령, 32비트, 32비트, 32비트, 32비트 등으로 나타낼 수 있습니다.int
식적 the the int
,float
,long
★★★★★★★★★★★★★★★★★」double
타입은 모두 JVM 검증자 규칙에 의한 명시적 변환이 필요한 바이트 코드 내에 존재합니다.
모니터 해제 안 함
A synchronized
블록은 실제로 취득할 문과 모니터를 릴리스할 문으로 구성됩니다.JBC, JBC, JBC, JBC 방송.
주의: HotSpot의 최근 구현에서는 대신 다음과 같은 오류가 발생합니다.IllegalMonitorStateException
메서드가 예외 자체에 의해 종료된 경우 또는 암묵적인 릴리스로 변환됩니다.
의 " " " 를 추가합니다.return
Java에서는 다음과 같은 사소한 유형의 이니셜라이저도
class Foo {
static {
return;
}
}
불법입니다.바이트 코드에서 타입 이니셜라이저는 다른 모든 방법과 동일하게 취급됩니다.즉, return 문은 어디에서나 정의할 수 있습니다.
축소할 수 없는 루프를 작성
Java 컴파일러는 루프를 Java 바이트 코드의 goto 문으로 변환합니다.이러한 문장은 Java 컴파일러에서는 절대 하지 않는 축소 불가능한 루프를 생성하기 위해 사용될 수 있습니다.
재귀 캐치 블록 정의
Java 바이트 코드에서 블록을 정의할 수 있습니다.
try {
throw new Exception();
} catch (Exception e) {
<goto on exception>
throw Exception();
}
됩니다.synchronized
이 경우 모니터를 릴리스하는 동안 예외가 발생하면 이 모니터를 릴리스하기 위한 명령으로 돌아갑니다.는 발생하지 않습니다된 명령어, 폐지된 명령어, 폐지된 명령어, 폐지된 명령어, 폐지된 명령어, 폐지된 경우에는 는 발생하지 않습니다.ThreadDeath
해 릴리스
기본 메서드를 호출합니다.
Java 컴파일러는 기본 메서드의 호출을 허용하기 위해 몇 가지 조건을 충족해야 합니다.
- 이 메서드는 가장 구체적인 메서드여야 합니다(슈퍼 타입을 포함한 모든 타입에 의해 구현되는 서브 인터페이스에 의해 덮어쓰지 마십시오).
- 기본 메서드의 인터페이스 유형은 기본 메서드를 호출하는 클래스에서 직접 구현해야 합니다. 인터페이스 「」의 는, 「」입니다.
B
" " " " "A
, 서서의 in in in in in in in in in in in의 .A
메서드는 아직 호출할 수 있습니다.
Java 바이트 코드의 경우 두 번째 조건만 카운트됩니다.하지만 첫번째 것은 무관하다.
on on on invoke invoke invoke invoke invoke that that that that that that 에서 슈퍼메서드를 합니다.this
인스턴스 기본값) 수.this
그러나 바이트 코드에서는 다음과 같은 유형의 인스턴스에서 super 메서드를 호출할 수도 있습니다.
class Foo {
void m(Foo f) {
f.super.toString(); // calls Object::toString
}
public String toString() {
return "foo";
}
}
모의 구성원에 대한 액세스
Java 바이트 코드에서는 합성 멤버에 직접 접속할 수 있습니다.를 들어,에서는 다른 인스턴스가 되어 있는지 해 보십시오.Bar
★★★★★★★★★★★★★★★★★★★:
class Foo {
class Bar {
void bar(Bar bar) {
Foo foo = bar.Foo.this;
}
}
}
이는 일반적으로 모든 합성 필드, 클래스 또는 메서드에 적용됩니다.
동기화되지 않은 일반 유형 정보 정의
Java 런타임은 범용 유형을 처리하지 않지만(Java 컴파일러가 유형 삭제를 적용한 후), 이 정보는 메타 정보로서 컴파일된 클래스에 부가되어 리플렉션 API를 통해 액세스할 수 있습니다.
는 이러한 .String
-values. -values.따라서 삭제와 일치하지 않는 범용 유형에 대한 정보를 정의할 수 있습니다.개념으로서 다음과 같은 주장이 참일 수 있다.
Method method = ...
assertTrue(method.getParameterTypes() != method.getGenericParameterTypes());
Field field = ...
assertTrue(field.getFieldType() == String.class);
assertTrue(field.getGenericFieldType() == Integer.class);
또, 시그니처는 무효라고 정의할 수 있기 때문에, 런타임 예외가 느려집니다.이 예외는 정보가 느슨하게 평가되기 때문에 처음 액세스할 때 발생합니다(오류가 있는 주석 값과 유사합니다).
특정 메서드에 대해서만 매개 변수 메타 정보 추가
를 컴파일할 때 할 수 .parameter
플래그를 유효하게 합니다.그러나 Java 클래스 파일 형식에서는 이 정보가 메서드별로 저장되므로 특정 메서드에 대해서만 이러한 메서드 정보를 포함할 수 있습니다.
JVM을 망가뜨리고 하드 크래시합니다.
예를 들어 Java 바이트 코드에서 임의의 유형의 메서드를 호출하도록 정의할 수 있습니다.일반적으로 검증자는 유형이 이러한 메서드를 인식하지 못할 경우 불만을 제기합니다.그러나 어레이에서 알 수 없는 메서드를 호출하면 일부 JVM 버전에서 버그가 발견되어 검증자가 이를 놓치고 명령이 호출되면 JVM이 종료됩니다.이 기능은 거의 없지만 자바 컴파일에서는 기술적으로 불가능한 기능입니다.자바에는 일종의 이중 검증 기능이 있습니다.첫 번째 검증은 Java 컴파일러에 의해 적용되며 두 번째 검증은 클래스가 로드될 때 JVM에 의해 적용됩니다.컴파일러를 건너뛰면 검증자의 유효성 검사에서 취약점이 발견될 수 있습니다.단, 이것은 특징이라기보다는 일반적인 설명입니다.
외부 클래스가 없을 때 생성자의 수신기 유형 주석 달기
Java 8 이후 내부 클래스의 비정적 메서드 및 컨스트럭터는 수신기 유형을 선언하고 이러한 유형에 주석을 달 수 있습니다.최상위 클래스의 생성자는 대부분 수신기 유형을 선언하지 않으므로 수신기 유형에 주석을 달 수 없습니다.
class Foo {
class Bar {
Bar(@TypeAnnotation Foo Foo.this) { }
}
Foo() { } // Must not declare a receiver type
}
★★Foo.class.getDeclaredConstructor().getAnnotatedReceiverType()
, ", ", ", Return, Return, Return, Return"은 됩니다.AnnotatedType
Foo
에 대한 유형 할 수 .Foo
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★이러한 주석은 나중에 리플렉션 API에 의해 읽힙니다.
미사용/기존 바이트 코드 명령 사용
다른 분들이 이름을 지었으니까 저도 같이 넣도록 하겠습니다..JSR
★★★★★★★★★★★★★★★★★」RET
목적을 위해 있었습니다.JBC는 이 목적을 위해 자체 유형의 리턴 주소도 알고 있었습니다.그러나 서브루틴을 사용하면 정적 코드 분석이 지나치게 복잡해지기 때문에 이러한 명령어는 더 이상 사용되지 않습니다.대신 자바 컴파일러는 컴파일한 코드를 복제합니다.그러나 이것은 기본적으로 동일한 논리를 만들어내기 때문에 나는 그것이 뭔가 다른 것을 성취하는 것이라고 생각하지 않는다.예를 '어울리다'를 도 있습니다.NOOP
자바 컴파일러에 의해 사용되지 않는 바이트 코드 명령도 있지만, 이것 또한 당신이 새로운 것을 얻는 것을 허락하지 않을 것입니다.문맥에서 지적한 바와 같이, 이러한 "기능 명령"은 이제 합법적인 opcode 집합에서 삭제되어 기능이 더 이상 되지 않습니다.
Java 6에서 지원되는 바이트 코드에는 Java 소스 코드에서도 액세스할 수 없는 주요 기능은 없는 것으로 알고 있습니다.그 주된 이유는 Java 바이트코드가 Java 언어를 염두에 두고 설계되었기 때문입니다.
단, 최신 Java 컴파일러에서는 지원되지 않는 기능이 있습니다.
플래그:
할 수 이며, 특정 합니다.
invokespecial
바이트 코드는 이 클래스에 대해 처리됩니다.현대의 모든 Java 컴파일러(내 기억이 맞다면 "현대"는 >= Java 1.1)에 의해 설정되며, 설정 해제된 클래스 파일은 고대 Java 컴파일러만 생성됩니다.이 플래그는 하위 호환성의 경우에만 존재합니다.Java 7u51은 ACC_SUPER를 사용합니다.jsr
/ret
바이트 코드바이트 실장에 은 「」를 실장하기 ).
finally
블록)을 클릭합니다.Java 6 이후 더 이상 생산되지 않습니다.이러한 코드 사용이 권장되지 않는 이유는 큰 이득이 없는 정적 검증이 매우 복잡하기 때문이다(즉, 사용하는 코드는 거의 항상 오버헤드가 거의 없는 정상적인 점프를 통해 재실현될 수 있다).반환 유형만 다른 두 개의 메서드가 클래스에 있습니다.
Java 언어 사양에서는 두 메서드가 반환 유형(즉, 동일한 이름, 동일한 인수 목록 등)에서만 다를 경우 동일한 클래스에 두 메서드를 사용할 수 없습니다.그러나 JVM 사양에는 이러한 제한이 없기 때문에 클래스 파일에는 두 가지 메서드가 포함될 수 있습니다.일반 Java 컴파일러를 사용하여 클래스 파일을 생성할 수 있는 방법은 없습니다.이 답변에는 좋은 예/설명이 있습니다.
Java 바이트 코드에서는 실행할 수 있지만 Java 소스 코드에서는 실행할 수 없는 몇 가지 기능을 다음에 나타냅니다.
메서드에서 체크된 예외를 슬로우한다고 선언하지 않고 메서드에서 슬로우합니다.체크 및 체크되지 않은 예외는 Java 컴파일러에서만 체크되며 JVM에서는 체크되지 않습니다.이 때문에 예를 들어 Scala는 체크된 예외를 선언하지 않고 메서드에서 슬로우할 수 있습니다.Java 제네릭스를 사용하는 경우에도 교활한 던지기라는 회피책이 있습니다.
요아힘의 답변에서 이미 언급한 바와 같이 반환 유형만 다른 두 가지 메서드가 클래스에 있습니다.Java 언어 사양에서는 두 메서드가 반환 유형(즉, 동일한 이름, 동일한 인수 목록 등)에서만 다를 경우 동일한 클래스에 두 메서드를 사용할 수 없습니다.그러나 JVM 사양에는 이러한 제한이 없기 때문에 클래스 파일에는 두 가지 메서드가 포함될 수 있습니다.일반 Java 컴파일러를 사용하여 클래스 파일을 생성할 수 있는 방법은 없습니다.이 답변에는 좋은 예/설명이 있습니다.
GOTO
과 함께 인 제어구조)를할 수 .for
while
etc )- 때 이 기호는 수 .
this
- 이 두 가지를 조합하면 테일콜 최적화 바이트 코드를 생성할 수 있습니다(JCompilo에서 이 작업을 수행합니다).
관련 포인트로 debug를 사용하여 컴파일하면 메서드의 파라미터 이름을 얻을 수 있습니다(파라머는 바이트 코드를 읽어냄으로써 이를 수행합니다).
이 문서의 섹션 7A는 바이트 코드 기능이 아닌 바이트 코드 함정에 대한 내용이지만, 관심이 있을 수 있습니다.
Java 언어에서 컨스트럭터의 첫 번째 문은 슈퍼 클래스 컨스트럭터에 대한 호출이어야 합니다.바이트 코드에는 이 제한이 없습니다.대신 멤버에 액세스하기 전에 오브젝트에 대해 슈퍼 클래스 컨스트럭터 또는 같은 클래스의 다른 컨스트럭터를 호출해야 합니다.이를 통해 다음과 같은 자유를 얻을 수 있습니다.
- 다른 객체의 인스턴스를 생성하여 로컬 변수(또는 스택)에 저장한 후 다른 용도로 사용할 수 있도록 해당 변수에 참조를 유지하면서 이를 매개 변수로 전달합니다.
- 조건에 따라 다른 컨스트럭터를 호출합니다.이것은 가능해야 합니다.Java에서 조건부로 다른 컨스트럭터를 호출하려면 어떻게 해야 합니까?
테스트 안 했으니까 틀렸으면 정정해 주세요.
일반적인 Java 코드 대신 바이트 코드로 할 수 있는 것은 컴파일러 없이 로드 및 실행할 수 있는 코드 생성입니다.많은 시스템에서 JDK가 아닌 JRE를 사용하고 있어 코드를 동적으로 생성하려면 Java 코드를 사용하기 전에 컴파일해야 하는 대신 바이트 코드를 생성하는 것이 더 나을 수 있습니다.
I-Play 때 바이트 코드 옵티마이저를 작성했습니다(J2ME 어플리케이션의 코드 사이즈를 줄이도록 설계되어 있습니다).추가된 기능 중 하나는 인라인 바이트 코드를 사용하는 기능(C++의 인라인 어셈블리 언어와 유사)입니다.값이 두 번 필요하기 때문에 DUP 명령을 사용하여 라이브러리 메서드의 일부인 함수의 크기를 줄일 수 있었습니다.또한 0바이트 명령도 있었습니다(캐스팅할 필요가 없는 메서드를 호출하고 int를 전달하려면 char(var)를 대체하기 위해 int2char(var)를 추가했습니다.이 명령어는 코드 크기를 줄이기 위해 i2c 명령을 삭제합니다).float a = 2.3, float b = 3.4, float c = a + b, float c = a + b로 변환하면 float point를 지원하지 않는 경우도 있습니다.
Java에서 보호된 메서드로 공용 메서드를 덮어쓰려고 하면(또는 다른 액세스 감소) "더 약한 액세스 권한 할당 시도" 오류가 발생합니다.JVM 바이트 코드로 하면 검증자는 문제없고 부모 클래스를 통해 이러한 메서드를 퍼블릭인 것처럼 호출할 수 있습니다.
언급URL : https://stackoverflow.com/questions/6827363/bytecode-features-not-available-in-the-java-language
'programing' 카테고리의 다른 글
Argparse 옵션 위치 인수? (0) | 2023.01.20 |
---|---|
판다 시리즈에서 원소 색인 찾기 (0) | 2023.01.20 |
Python 메서드에서 "self" 인수가 명시적으로 필요한 이유는 무엇입니까? (0) | 2023.01.20 |
모듈 외부에서 Vuex getter에 액세스할 수 없음 (0) | 2023.01.10 |
Curl POST 요청 헤더 표시?방법이 있을까요? (0) | 2023.01.10 |