Equivalents were produced with C++ to Java Converter and Java to C++ Converter.
Java | C++ |
---|---|
public abstract class AbstractClass { protected abstract void AbstractMethod(); } |
class AbstractClass { protected: virtual void AbstractMethod() = 0; }; |
The closest equivalent to Java anonymous inner classes in C++ is to use a private class which implements the corresponding interface (but if the interface is a functional interface, then the closest equivalent is to replace the functional interface with a function pointer and the anonymous inner class with a lambda).
Java | C++ |
---|---|
public class TestClass { private void TestMethod() { MyInterface localVar = new MyInterface() { public void method1() { someCode(); } public void method2(int i, boolean b) { someCode(); } }; } } |
class TestClass { private: void TestMethod() { MyInterface *localVar = new MyInterfaceAnonymousInnerClass(this); } private: class MyInterfaceAnonymousInnerClass : public MyInterface { private: TestClass *outerInstance; public: MyInterfaceAnonymousInnerClass(TestClass *outerInstance) { this->outerInstance = outerInstance; } void method1() { someCode(); } void method2(int i, bool b) { someCode(); } }; }; |
Sized Array
C++ | Java |
---|---|
int myArray[2]; or: int *myArray = new int[2]; |
int[] myArray = new int[2]; |
Access Array Element
C++ | Java |
---|---|
x = myArray[0]; | x = myArray[0]; |
Jagged Array
C++ | Java |
---|---|
int **myArray = new int*[2]; | int[][] myArray = new int[2][]; |
Rectangular Array
C++ | Java |
---|---|
int myArray[2][3]; |
int[][] myArray = new int[2][3]; |
Java | C++ |
---|---|
x = (FooType)myObject; | x = static_cast<FooType*>(myObject); |
C++ | Java |
---|---|
// vector: std::vector<int> myList = {1, 2, 3}; // unordered_map: std::unordered_map<std::wstring, int> myD = { {string1, 80}, {string2, 85} }; |
import java.util.*; // ArrayList: (Java 9 List.of would also work here) ArrayList<Integer> myList = new ArrayList<Integer>(Arrays.asList(1, 2, 3)); // HashMap: (Map.ofEntries requires Java 9) HashMap<String, Integer> myD = new HashMap<String, Integer>(Map.ofEntries(Map.entry(string1, 80), Map.entry(string2, 85))); |
Vectors (C++) and ArrayLists (Java)
C++ | Java |
---|---|
#include <vector> void Vector() { std::vector<int> myList; myList.push_back(1); int i = 1; myList[0] = i; i = myList[0]; } |
import java.util.*; private void Vector() { ArrayList<Integer> myList = new ArrayList<Integer>(); myList.add(1); int i = 1; myList.set(0, i); i = myList.get(0); } |
Maps (C++) and HashMaps (Java)
(std::map and java.util.TreeMap are also very close equivalents).
C++ | Java |
---|---|
#include <string> #include <unordered_map> void UnorderedMap() { std::unordered_map<std::wstring, int> map; std::wstring s = L"test"; map.emplace(s, 1); int i = map[s]; i = map.size(); bool b = map.empty(); map.erase(s); } |
import java.util.*; private void UnorderedMap() { HashMap<String, Integer> map = new HashMap<String, Integer>(); String s = "test"; map.put(s, 1); int i = map.get(s); i = map.size(); boolean b = map.isEmpty(); map.remove(s); } |
Local Constant
C++ | Java |
---|---|
constexpr int myConst = 2; | final int myConst = 2; |
Class Constant
C++ | Java |
---|---|
public: static constexpr int myConst = 2; |
public static final int myConst = 2; |
Local Variable
C++ | Java |
---|---|
int myVar = 2; | int myVar = 2; |
Inferred Types
There is no inferred typing in Java, so the type is inferred by the converter:
C++ | Java |
---|---|
auto myVar = 2; | int myVar = 2; |
Static Field
C++ | Java |
---|---|
public: static inline int S = 0; |
public static int S = 0; |
Read-Only Field
C++ | Java |
---|---|
public: const int R = 2; |
public final int R = 2; |
The implementation of the 'close' method in the Closeable interface can be converted to a C++ destructor, but this is not exactly equivalent.
Java | C++ |
---|---|
class Foo implements java.io.Closeable { public Foo() { this(0); // call to other constructor } public Foo(int i) { } public final void close() { } } |
class Foo { public: Foo() : Foo(0) // call to other constructor { } Foo(int i) { } ~Foo() // destructor { } }; |
C++ | Java |
---|---|
int/signed int long/long int/signed long/signed long int long long/long long int signed long long/signed long long int short/short int signed short/signed short int unsigned/unsigned int unsigned long/unsigned long int unsigned short/unsigned short int unsigned long long/unsigned long long int bool char/wchar_t signed char unsigned char float double/long double std::wstring (no C++ language built-in type) std::any (C++17) or void * (no C++ language built-in type) |
int int (may convert to 'long' on some systems) long long short short no unsigned types in Java no unsigned types in Java no unsigned types in Java no unsigned types in Java boolean char byte (signed byte) no unsigned types in Java float double java.lang.String (no Java language built-in type) java.lang.Object (no Java language built-in type) |
Java does not allow optional parameters. Overloaded methods are the only alternative in Java to optional parameters (these are inserted into the converted code by C++ to Java Converter). A C++ method with n optional parameters is converted to n + 1 overloaded methods. The overloaded methods call the overloaded method with the maximum number of parameters (which contains your original method code), passing the default values originally specified for the original optional parameters.
Here's an example of the simplest possible case:
C++ | Java |
---|---|
void TestOptional(int x = 0) { ... } |
public void TestOptional() { TestOptional(0); } public void TestOptional(int x) { ... } |
Simple enums in Java have simple equivalents in C++:
Java | C++ |
---|---|
public enum Simple { FOO, BAR } |
enum class Simple { FOO, BAR }; |
More complex enums in Java unfortunately have exceedingly complex equivalents in C++:
Java | C++ |
---|---|
public enum Complex { FOO("Foo"), BAR("Bar"); private final String value; Complex(String enumValue) { this.value = enumValue; } public void InstanceMethod() { // ... } } |
#include <string> #include <vector> class Complex final { public: static inline Complex FOO(L"FOO", InnerEnum::FOO, L"Foo"); static inline Complex BAR(L"BAR", InnerEnum::BAR, L"Bar"); private: static inline std::vector<Complex> valueList; class StaticConstructor { public: StaticConstructor() { valueList.push_back(FOO); valueList.push_back(BAR); } }; static inline StaticConstructor staticConstructor; public: enum class InnerEnum { FOO, BAR }; const InnerEnum innerEnumValue; private: const std::wstring nameValue; const int ordinalValue; static inline int nextOrdinal = 0; const std::wstring value; public: Complex(const std::wstring &name, InnerEnum innerEnum, const std::wstring &enumValue) : nameValue(name), ordinalValue(nextOrdinal++), innerEnumValue(innerEnum) { this->value = enumValue; } virtual void InstanceMethod() { // ... } bool operator == (const Complex &other) { return this->ordinalValue == other.ordinalValue; } bool operator != (const Complex &other) { return this->ordinalValue != other.ordinalValue; } static std::vector<Complex> values() { return valueList; } int ordinal() { return ordinalValue; } std::wstring toString() { return nameValue; } static Complex valueOf(const std::wstring &name) { for (auto enumInstance : Complex::valueList) { if (enumInstance.nameValue == name) { return enumInstance; } } } }; |
The C++ 'range for' syntax and Java 'for each' syntax is identical:
C++ | Java |
---|---|
for (std::string s : StringList) { ... } |
for (String s : StringList) { ... } |
C++ function pointer typedefs correspond to Java functional interfaces.
Here's an example using two different formats for function pointer typedefs:
C++ | Java |
---|---|
class TestFunctionPointers { typedef void(TestFunctionPointers::*Foo1)(); using Foo2 = void(TestFunctionPointers::*)(); // C++11 syntax void method() { Foo1 TestPtr1 = &TestFunctionPointers::matchedMethod; (this->*TestPtr1)(); Foo2 TestPtr2 = &TestFunctionPointers::matchedMethod; (this->*TestPtr2)(); } void matchedMethod() { } }; |
public class TestFunctionPointers { @FunctionalInterface private interface Foo1 { void invoke(); } @FunctionalInterface private interface Foo2 { void invoke(); } private void method() { Foo1 TestPtr1 = () -> this.matchedMethod(); TestPtr1.invoke(); Foo2 TestPtr2 = () -> this.matchedMethod(); TestPtr2.invoke(); } private void matchedMethod() { } } |
Java generics and C++ templates are implemented in totally different ways — Java generics uses the concept of 'type erasure' (compiling to Object and casts), while C++ templates result in separate classes created at compile-time, but you can usually achieve the same result by converting one to the other.
Creating a List
Java | C++ |
---|---|
ArrayList<Integer> myVar = new ArrayList<Integer>(); | std::vector<int> myVar; |
Creating a Dictionary
Java | C++ |
---|---|
HashMap<String, Integer> myVar = new HashMap<String, Integer>(); | std::unordered_map<std::string, int> myVar; |
Defining a Generic Class
Java | C++ |
---|---|
public class GenericClass<T> { } |
template<typename T> class GenericClass { }; |
Defining a Generic Class with a Constraint
Java | C++ |
---|---|
public class GenericClass<T extends SomeBase> { } |
#include <type_traits> template<typename T> class GenericClass { static_assert(std::is_base_of<SomeBase, T>::value, "T must inherit from SomeBase"); }; |
Defining a Generic Method
Java | C++ |
---|---|
public <T> int Compare(T param1, T param2) { } |
public: template<typename T> int Compare(T param1, T param2) { } |
Defining a Generic Method with a Constraint
Java | C++ |
---|---|
public <T extends SomeBase> int Compare(T param1, T param2) { } |
#include <type_traits> public: template<typename T> int Compare(T param1, T param2) { static_assert(std::is_base_of<SomeBase, T>::value, "T must inherit from SomeBase"); } |
Java | C++ |
---|---|
import Foo.*; import static Foo.Bar.*; |
using namespace Foo; *no equivalent* |
Java does not have indexers, so you must use get/set methods instead:
C++ | Java |
---|---|
public: int &operator [](int index) { return field[index]; } |
public final int get(int index) { return field[index]; } public final void set(int index, int value) { field[index] = value; } |
C++ | Java |
---|---|
class DerivedClass : public BaseClass { public: virtual void MethodOverrideOne() override { } virtual void MethodOverrideTwo() final override { } }; |
public class DerivedClass extends BaseClass { @Override public void MethodOverrideOne() { } @Override public final void MethodOverrideTwo() { } } |
C++ doesn't have a separate 'interface' concept, but this is done just as easily in C++ using a class with only 'pure virtual methods'.
Java | C++ |
---|---|
public interface IFoo { void Method(); } |
class IFoo { public: // pure virtual method: virtual void Method() = 0; }; |
C++ | Java |
---|---|
myVar = [&] (const std::string &text) { return text.length(); }; |
myVar = (string text) -> { return text.Length; } |
In C++17, the std::any type offers a good equivalent to java.lang.Object.
Java | C++ (C++17) |
---|---|
java.lang.Object o = 1; int i = (int)o; java.lang.Class t = o.getClass(); |
#include <any> #include <typeinfo> std::any o = 1; int i = std::any_cast<int>(o); std::type_info t = o.type(); |
Java doesn't offer operator overloading, so you have to create instance methods in the place of operator overloads:
C++ | Java |
---|---|
class SomeType { private: int IntValue = 0; public: int operator + (const SomeType &Y) { return this->IntValue + Y.IntValue; } void test() { SomeType o1, o2; int i = o1 + o2; } }; |
public class SomeType { private int IntValue = 0; public int add (SomeType Y) { return this.IntValue + Y.IntValue; } public void test() { SomeType o1 = new SomeType(); SomeType o2 = new SomeType(); int i = o1.add(o2); } } |
Java | C++ |
---|---|
package FooPackage; // only one per file public class FooClass { } |
namespace FooPackage // can have many per file { class FooClass { }; } |
C++ | Java |
---|---|
// raw pointer: Foo *f1 = new Foo(); // 'smart' pointer: std::shared_ptr<Foo> f2 = std::make_shared<Foo>(); |
Foo f1 = new Foo(); Foo f2 = new Foo(); |
Java doesn't have raw string literals before Java 15 text blocks, so the closest you can get is a string concatenation which spans multiple lines. Java 15 rules about indentation in text blocks are very convoluted however.
C++ | Java |
---|---|
std::string s = R"(multiline raw string)"; |
// pre-Java 15: String s = "multiline" + "\r\n" + " raw" + "\r\n" + " string"; // Java 15 text blocks: String s = """ multiline raw string"""; |
The C++ equivalent to a Java static initializer block uses a private nested class.
Java | C++ |
---|---|
class Foo { public static int field; static { field = 1; } } |
class Foo { public: static inline int field = 0; private: class StaticConstructor { public: StaticConstructor() { field = 1; } }; private: static inline Foo::StaticConstructor staticConstructor; }; |
Java | C++ (C++17) |
---|---|
synchronized (x) { ... } |
#include <mutex> ... { std::scoped_lock<std::mutex> lock(x); ...... } |
Java | C++ |
---|---|
try (Foo f = new Foo()) { f.method(); } |
{ Foo *f = new Foo(); f->method(); delete f; } or, if 'Foo' is designed for RAII: { Foo f; f.method(); } |
There is no direct equivalent in C++ to the Java 'instanceof' operator, but you can replicate the behavior by testing the result of a 'dynamic_cast':
Java | C++ |
---|---|
boolean b = f instanceof Foo; | bool b = dynamic_cast<Foo*>(f) != nullptr; |
Copyright © 2004 – 2024 Tangible Software Solutions, Inc.